import Foundation
import ComposeApp
import WidgetKit

/// Processes pending actions queued by the widget extension
/// Call `processPendingActions()` when the app becomes active
@MainActor
final class WidgetActionProcessor {
    static let shared = WidgetActionProcessor()

    /// Maximum number of retry attempts per action before giving up
    private static let maxRetries = 3

    /// Tracks retry counts by action description (taskId)
    private var retryCounts: [Int: Int] = [:]

    private init() {}

    /// Check if there are pending widget actions to process
    var hasPendingActions: Bool {
        WidgetDataManager.shared.hasPendingActions
    }

    /// Process all pending widget actions
    /// Should be called when app becomes active
    func processPendingActions() {
        guard DataManager.shared.isAuthenticated() else {
            print("WidgetActionProcessor: Not authenticated, skipping action processing")
            return
        }

        Task {
            let actions = await WidgetDataManager.shared.loadPendingActions()
            guard !actions.isEmpty else {
                print("WidgetActionProcessor: No pending actions")
                return
            }

            print("WidgetActionProcessor: Processing \(actions.count) pending action(s)")

            for action in actions {
                await processAction(action)
            }
        }
    }

    /// Process a single widget action
    private func processAction(_ action: WidgetDataManager.WidgetAction) async {
        switch action {
        case .completeTask(let taskId, let taskTitle):
            await completeTask(taskId: taskId, taskTitle: taskTitle, action: action)
        }
    }

    /// Complete a task via the API
    private func completeTask(taskId: Int, taskTitle: String, action: WidgetDataManager.WidgetAction) async {
        print("WidgetActionProcessor: Completing task \(taskId) - \(taskTitle)")

        do {
            // Create a task completion with default values (quick complete from widget)
            let request = TaskCompletionCreateRequest(
                taskId: Int32(taskId),
                completedAt: nil,  // Defaults to now on server
                notes: "Completed from widget",
                actualCost: nil,
                rating: nil,
                uploadIds: nil
            )

            let result = try await APILayer.shared.createTaskCompletion(request: request)

            if result is ApiResultSuccess<TaskCompletionResponse> {
                print("WidgetActionProcessor: Task \(taskId) completed successfully")
                // Remove the processed action and clear pending state
                WidgetDataManager.shared.removeAction(action)
                WidgetDataManager.shared.clearPendingState(forTaskId: taskId)
                retryCounts.removeValue(forKey: taskId)
                // Refresh tasks to update UI
                await refreshTasks()
            } else if let error = ApiResultBridge.error(from: result) {
                print("WidgetActionProcessor: Failed to complete task \(taskId): \(error.message)")
                handleRetryOrDiscard(taskId: taskId, action: action, reason: error.message)
            }
        } catch {
            print("WidgetActionProcessor: Error completing task \(taskId): \(error)")
            handleRetryOrDiscard(taskId: taskId, action: action, reason: error.localizedDescription)
        }
    }

    /// Increment retry count; discard action only after maxRetries.
    /// On failure, clear pending state so the task reappears in the widget.
    private func handleRetryOrDiscard(taskId: Int, action: WidgetDataManager.WidgetAction, reason: String) {
        let attempts = (retryCounts[taskId] ?? 0) + 1
        retryCounts[taskId] = attempts

        if attempts >= Self.maxRetries {
            print("WidgetActionProcessor: Task \(taskId) failed after \(attempts) attempts (\(reason)). Discarding action.")
            WidgetDataManager.shared.removeAction(action)
            WidgetDataManager.shared.clearPendingState(forTaskId: taskId)
            retryCounts.removeValue(forKey: taskId)
        } else {
            print("WidgetActionProcessor: Task \(taskId) attempt \(attempts)/\(Self.maxRetries) failed (\(reason)). Keeping for retry.")
            // Clear pending state so the task is visible in the widget again,
            // but keep the action so it will be retried next time the app becomes active.
            WidgetDataManager.shared.clearPendingState(forTaskId: taskId)
        }
    }

    /// Refresh tasks from the server to update UI and widget
    private func refreshTasks() async {
        do {
            let result = try await APILayer.shared.getTasks(forceRefresh: true)
            if let success = result as? ApiResultSuccess<TaskColumnsResponse>,
               let data = success.data {
                // Update widget with fresh data
                WidgetDataManager.shared.saveTasks(from: data)
                // Summary is calculated client-side by DataManager.setAllTasks() -> refreshSummaryFromKanban()
            }
        } catch {
            print("WidgetActionProcessor: Error refreshing tasks: \(error)")
        }
    }
}
