import SwiftUI
import ComposeApp

// MARK: - Field Focus Enum
enum TaskFormField {
    case title, description, intervalDays, estimatedCost
}

// MARK: - Task Form View
struct TaskFormView: View {
    let residenceId: Int32?
    let residences: [ResidenceResponse]?
    let existingTask: TaskResponse? // nil for add mode, populated for edit mode
    @Binding var isPresented: Bool
    @StateObject private var viewModel = TaskViewModel()
    @ObservedObject private var dataManager = DataManagerObservable.shared
    @FocusState private var focusedField: TaskFormField?

    private var isEditMode: Bool {
        existingTask != nil
    }

    private var needsResidenceSelection: Bool {
        residenceId == nil && !isEditMode
    }

    private var canSave: Bool {
        !title.isEmpty &&
        (!needsResidenceSelection || selectedResidence != nil) &&
        selectedCategory != nil &&
        selectedFrequency != nil &&
        selectedPriority != nil
    }

    // Lookups from DataManagerObservable
    private var taskCategories: [TaskCategory] { dataManager.taskCategories }
    private var taskFrequencies: [TaskFrequency] { dataManager.taskFrequencies }
    private var taskPriorities: [TaskPriority] { dataManager.taskPriorities }
    private var isLoadingLookups: Bool { !dataManager.lookupsInitialized }

    // Form fields
    @State private var selectedResidence: ResidenceResponse?
    @State private var title: String
    @State private var description: String
    @State private var selectedCategory: TaskCategory?
    @State private var selectedFrequency: TaskFrequency?
    @State private var selectedPriority: TaskPriority?
    @State private var inProgress: Bool
    @State private var hasDueDate: Bool
    @State private var dueDate: Date
    @State private var intervalDays: String
    @State private var estimatedCost: String

    // Initialize form fields based on mode (add vs edit)
    init(residenceId: Int32? = nil, residences: [ResidenceResponse]? = nil, existingTask: TaskResponse? = nil, isPresented: Binding<Bool>) {
        self.residenceId = residenceId
        self.residences = residences
        self.existingTask = existingTask
        self._isPresented = isPresented

        // Initialize fields from existing task or with defaults
        if let task = existingTask {
            _title = State(initialValue: task.title)
            _description = State(initialValue: task.description_ ?? "")
            _selectedCategory = State(initialValue: task.category)
            _selectedFrequency = State(initialValue: task.frequency)
            _selectedPriority = State(initialValue: task.priority)
            _inProgress = State(initialValue: task.inProgress)

            // Parse date from string - use effective due date (nextDueDate if set, otherwise dueDate)
            let parsedDate = (task.effectiveDueDate ?? "").toDate()
            _hasDueDate = State(initialValue: parsedDate != nil)
            _dueDate = State(initialValue: parsedDate ?? Date())

            _intervalDays = State(initialValue: task.customIntervalDays.map { "\($0.int32Value)" } ?? "")
            _estimatedCost = State(initialValue: task.estimatedCost != nil ? String(task.estimatedCost!.doubleValue) : "")
        } else {
            _title = State(initialValue: "")
            _description = State(initialValue: "")
            _inProgress = State(initialValue: false)
            _hasDueDate = State(initialValue: true)
            _dueDate = State(initialValue: Date())
            _intervalDays = State(initialValue: "")
            _estimatedCost = State(initialValue: "")
        }
    }

    // Validation errors
    @State private var titleError: String = ""
    @State private var residenceError: String = ""

    // Error alert state
    @State private var errorAlert: ErrorAlertInfo? = nil

    // Template suggestions
    @State private var showingTemplatesBrowser = false
    @State private var filteredSuggestions: [TaskTemplate] = []
    @State private var showSuggestions = false

    var body: some View {
        NavigationStack {
            Form {
                    // Residence Picker (only if needed)
                    if needsResidenceSelection, let residences = residences {
                        Section {
                            Picker(L10n.Tasks.property, selection: $selectedResidence) {
                                ForEach(residences, id: \.id) { residence in
                                    Text(residence.name).tag(residence as ResidenceResponse?)
                                }
                            }
                            .accessibilityIdentifier(AccessibilityIdentifiers.Task.residencePicker)

                            if !residenceError.isEmpty {
                                FieldError(message: residenceError)
                            }
                        } header: {
                            Text(L10n.Tasks.property)
                        }
                        .sectionBackground()
                    }

                    // Browse Templates Button (only for new tasks)
                    if !isEditMode {
                        Section {
                            Button {
                                showingTemplatesBrowser = true
                            } label: {
                                HStack(spacing: 14) {
                                    ZStack {
                                        Circle()
                                            .fill(Color.appPrimary.opacity(0.12))
                                            .frame(width: 40, height: 40)
                                        Image(systemName: "list.bullet.rectangle")
                                            .font(.system(size: 16, weight: .semibold))
                                            .foregroundColor(Color.appPrimary)
                                    }

                                    VStack(alignment: .leading, spacing: 2) {
                                        Text("Browse Task Templates")
                                            .font(.system(size: 16, weight: .semibold, design: .rounded))
                                            .foregroundColor(Color.appTextPrimary)

                                        Text("\(dataManager.taskTemplateCount) common tasks")
                                            .font(.system(size: 13, weight: .medium))
                                            .foregroundColor(Color.appTextSecondary)
                                    }

                                    Spacer()

                                    Image(systemName: "chevron.right")
                                        .font(.system(size: 14, weight: .medium))
                                        .foregroundColor(Color.appTextSecondary)
                                }
                                .padding(.vertical, 4)
                            }
                        } header: {
                            Text("Quick Start")
                                .font(.system(size: 13, weight: .semibold, design: .rounded))
                        } footer: {
                            Text("Choose from common home maintenance tasks or create your own below")
                                .font(.system(size: 12, weight: .medium))
                                .foregroundColor(Color.appTextSecondary)
                        }
                        .sectionBackground()
                    }

                    Section {
                        VStack(alignment: .leading, spacing: 8) {
                            TextField(L10n.Tasks.titleLabel, text: $title)
                                .focused($focusedField, equals: .title)
                                .accessibilityIdentifier(AccessibilityIdentifiers.Task.titleField)
                                .onChange(of: title) { _, newValue in
                                    updateSuggestions(query: newValue)
                                }

                            // Inline suggestions dropdown
                            if showSuggestions && !filteredSuggestions.isEmpty && focusedField == .title {
                                TaskSuggestionsView(
                                    suggestions: filteredSuggestions,
                                    onSelect: { template in
                                        selectTaskTemplate(template)
                                    }
                                )
                            }
                        }

                        if !titleError.isEmpty {
                            FieldError(message: titleError)
                        }

                        TextField(L10n.Tasks.descriptionOptional, text: $description, axis: .vertical)
                            .lineLimit(3...6)
                            .focused($focusedField, equals: .description)
                            .accessibilityIdentifier(AccessibilityIdentifiers.Task.descriptionField)
                    } header: {
                        Text(L10n.Tasks.taskDetails)
                            .accessibilityAddTraits(.isHeader)
                    } footer: {
                        Text(L10n.Tasks.titleRequired)
                            .font(.caption)
                            .foregroundColor(Color.appError)
                    }
                    .sectionBackground()

                    Section {
                        Picker(L10n.Tasks.category, selection: $selectedCategory) {
                            Text(L10n.Tasks.selectCategory).tag(nil as TaskCategory?)
                            ForEach(taskCategories, id: \.id) { category in
                                Text(category.name.capitalized).tag(category as TaskCategory?)
                            }
                        }
                        .accessibilityIdentifier(AccessibilityIdentifiers.Task.categoryPicker)
                    } header: {
                        Text(L10n.Tasks.category)
                    }
                    .sectionBackground()

                    Section {
                        Picker(L10n.Tasks.frequency, selection: $selectedFrequency) {
                            Text(L10n.Tasks.selectFrequency).tag(nil as TaskFrequency?)
                            ForEach(taskFrequencies, id: \.id) { frequency in
                                Text(frequency.displayName).tag(frequency as TaskFrequency?)
                            }
                        }
                        .accessibilityIdentifier(AccessibilityIdentifiers.Task.frequencyPicker)
                        .onChange(of: selectedFrequency) { _, newFrequency in
                            // Clear interval days if not Custom frequency
                            if newFrequency?.name.lowercased() != "custom" {
                                intervalDays = ""
                            }
                        }

                        // Show custom interval field only for "Custom" frequency
                        if selectedFrequency?.name.lowercased() == "custom" {
                            TextField(L10n.Tasks.customInterval, text: $intervalDays)
                                .keyboardType(.numberPad)
                                .focused($focusedField, equals: .intervalDays)
                                .accessibilityIdentifier(AccessibilityIdentifiers.Task.intervalDaysField)
                        }

                        Toggle(L10n.Tasks.dueDate, isOn: $hasDueDate)

                        if hasDueDate {
                            DatePicker(L10n.Tasks.dueDate, selection: $dueDate, displayedComponents: .date)
                                .accessibilityIdentifier(AccessibilityIdentifiers.Task.dueDatePicker)
                        }
                    } header: {
                        Text(L10n.Tasks.scheduling)
                            .accessibilityAddTraits(.isHeader)
                    } footer: {
                        if selectedFrequency?.name.lowercased() == "custom" {
                            Text("Enter the number of days between each occurrence")
                                .font(.caption)
                                .foregroundColor(Color.appTextSecondary)
                        }
                    }
                    .sectionBackground()

                    Section {
                        Picker(L10n.Tasks.priority, selection: $selectedPriority) {
                            Text(L10n.Tasks.selectPriority).tag(nil as TaskPriority?)
                            ForEach(taskPriorities, id: \.id) { priority in
                                Text(priority.displayName).tag(priority as TaskPriority?)
                            }
                        }
                        .accessibilityIdentifier(AccessibilityIdentifiers.Task.priorityPicker)

                        Toggle(L10n.Tasks.inProgressLabel, isOn: $inProgress)
                    } header: {
                        Text(L10n.Tasks.priorityAndStatus)
                            .accessibilityAddTraits(.isHeader)
                    }
                    .sectionBackground()

                    Section(header: Text(L10n.Tasks.cost)) {
                        TextField(L10n.Tasks.estimatedCost, text: $estimatedCost)
                            .keyboardType(.decimalPad)
                            .focused($focusedField, equals: .estimatedCost)
                            .accessibilityIdentifier(AccessibilityIdentifiers.Task.estimatedCostField)
                    }
                    .sectionBackground()

                    if let errorMessage = viewModel.errorMessage {
                        Section {
                            Text(errorMessage)
                                .foregroundColor(Color.appError)
                                .font(.caption)
                        }
                        .sectionBackground()
                    }
                }
            .loadingOverlay(isLoading: isLoadingLookups, message: L10n.Tasks.loading)
            .standardFormStyle()
            .navigationTitle(isEditMode ? L10n.Tasks.editTitle : L10n.Tasks.addTitle)
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button(L10n.Common.cancel) {
                        isPresented = false
                    }
                    .disabled(isLoadingLookups)
                    .accessibilityIdentifier(AccessibilityIdentifiers.Task.formCancelButton)
                }

                ToolbarItem(placement: .navigationBarTrailing) {
                    Button(isEditMode ? L10n.Common.save : L10n.Common.add) {
                        submitForm()
                    }
                    .disabled(!canSave || viewModel.isLoading || isLoadingLookups)
                    .accessibilityIdentifier(AccessibilityIdentifiers.Task.saveButton)
                }

                ToolbarItemGroup(placement: .keyboard) {
                    Spacer()
                    Button("Done") {
                        focusedField = nil
                    }
                    .foregroundColor(Color.appPrimary)
                    .fontWeight(.medium)
                }
            }
            .onAppear {
                // Track screen view for new tasks
                if !isEditMode {
                    AnalyticsManager.shared.trackScreen(.newTask)
                }
                // Set defaults when lookups are available
                if dataManager.lookupsInitialized {
                    setDefaults()
                }
            }
            .onChange(of: dataManager.lookupsInitialized) { _, initialized in
                if initialized {
                    setDefaults()
                }
            }
            .onChange(of: viewModel.taskCreated) { _, created in
                if created {
                    viewModel.resetActionState()
                    isPresented = false
                }
            }
            .onChange(of: viewModel.errorMessage) { _, errorMessage in
                if let errorMessage = errorMessage, !errorMessage.isEmpty {
                    errorAlert = ErrorAlertInfo(message: errorMessage)
                }
            }
            .errorAlert(
                error: errorAlert,
                onRetry: {
                    errorAlert = nil
                    submitForm()
                },
                onDismiss: {
                    errorAlert = nil
                }
            )
            .sheet(isPresented: $showingTemplatesBrowser) {
                TaskTemplatesBrowserView { template in
                    selectTaskTemplate(template)
                }
            }
        }
    }

    // MARK: - Suggestions Helpers

    private func updateSuggestions(query: String) {
        if query.count >= 2 {
            filteredSuggestions = dataManager.searchTaskTemplates(query: query)
            showSuggestions = !filteredSuggestions.isEmpty
        } else {
            filteredSuggestions = []
            showSuggestions = false
        }
    }

    private func selectTaskTemplate(_ template: TaskTemplate) {
        // Fill in the title
        title = template.title

        // Fill in description if available
        description = template.description_

        // Auto-select matching category by ID or name
        if let categoryId = template.categoryId {
            selectedCategory = taskCategories.first(where: { $0.id == Int(categoryId.int32Value) })
        } else if let category = template.category {
            selectedCategory = taskCategories.first(where: { $0.name.lowercased() == category.name.lowercased() })
        }

        // Auto-select matching frequency by ID or name
        if let frequencyId = template.frequencyId {
            selectedFrequency = taskFrequencies.first(where: { $0.id == Int(frequencyId.int32Value) })
        } else if let frequency = template.frequency {
            selectedFrequency = taskFrequencies.first(where: { $0.name.lowercased() == frequency.name.lowercased() })
        }

        // Clear suggestions and dismiss keyboard
        showSuggestions = false
        filteredSuggestions = []
        focusedField = nil
    }

    private func setDefaults() {
        // Set default values if not already set
        if selectedCategory == nil && !taskCategories.isEmpty {
            selectedCategory = taskCategories.first
        }

        if selectedFrequency == nil && !taskFrequencies.isEmpty {
            // Default to "once"
            selectedFrequency = taskFrequencies.first { $0.name == "once" } ?? taskFrequencies.first
        }

        if selectedPriority == nil && !taskPriorities.isEmpty {
            // Default to "medium"
            selectedPriority = taskPriorities.first { $0.name == "medium" } ?? taskPriorities.first
        }

        // Set default residence if provided
        if needsResidenceSelection && selectedResidence == nil, let residences = residences, !residences.isEmpty {
            selectedResidence = residences.first
        }
    }

    private func validateForm() -> Bool {
        var isValid = true

        if title.isEmpty {
            titleError = "Title is required"
            isValid = false
        } else {
            titleError = ""
        }

        if needsResidenceSelection && selectedResidence == nil {
            residenceError = "Property is required"
            isValid = false
        } else {
            residenceError = ""
        }

        if selectedCategory == nil {
            viewModel.errorMessage = "Please select a category"
            isValid = false
        }

        if selectedFrequency == nil {
            viewModel.errorMessage = "Please select a frequency"
            isValid = false
        }

        if selectedPriority == nil {
            viewModel.errorMessage = "Please select a priority"
            isValid = false
        }

        if !intervalDays.isEmpty, Int32(intervalDays) == nil {
            viewModel.errorMessage = "Custom interval must be a valid number"
            isValid = false
        }

        return isValid
    }

    private func submitForm() {
        guard validateForm() else { return }

        guard let category = selectedCategory,
              let frequency = selectedFrequency,
              let priority = selectedPriority else {
            return
        }

        // Format date as yyyy-MM-dd using extension, or nil if no due date
        let dueDateString: String? = hasDueDate ? dueDate.formattedAPI() : nil

        if isEditMode, let task = existingTask {
            // UPDATE existing task
            // Include customIntervalDays only for "Custom" frequency
            let customInterval: KotlinInt? = frequency.name.lowercased() == "custom" && !intervalDays.isEmpty
                ? KotlinInt(int: Int32(intervalDays) ?? 0)
                : nil

            let request = TaskCreateRequest(
                residenceId: task.residenceId,
                title: title,
                description: description.isEmpty ? nil : description,
                categoryId: KotlinInt(int: Int32(category.id)),
                priorityId: KotlinInt(int: Int32(priority.id)),
                inProgress: inProgress,
                frequencyId: KotlinInt(int: Int32(frequency.id)),
                customIntervalDays: customInterval,
                assignedToId: nil,
                dueDate: dueDateString,
                estimatedCost: estimatedCost.isEmpty ? nil : KotlinDouble(double: Double(estimatedCost) ?? 0.0),
                contractorId: nil,
                templateId: nil
            )

            viewModel.updateTask(id: task.id, request: request) { success in
                if success {
                    isPresented = false
                }
            }
        } else {
            // CREATE new task
            // Determine the actual residence ID to use
            let actualResidenceId: Int32
            if let providedId = residenceId {
                actualResidenceId = providedId
            } else if let selected = selectedResidence {
                actualResidenceId = Int32(selected.id)
            } else {
                return
            }

            // Include customIntervalDays only for "Custom" frequency
            let customIntervalCreate: KotlinInt? = frequency.name.lowercased() == "custom" && !intervalDays.isEmpty
                ? KotlinInt(int: Int32(intervalDays) ?? 0)
                : nil

            let request = TaskCreateRequest(
                residenceId: actualResidenceId,
                title: title,
                description: description.isEmpty ? nil : description,
                categoryId: KotlinInt(int: Int32(category.id)),
                priorityId: KotlinInt(int: Int32(priority.id)),
                inProgress: inProgress,
                frequencyId: KotlinInt(int: Int32(frequency.id)),
                customIntervalDays: customIntervalCreate,
                assignedToId: nil,
                dueDate: dueDateString,
                estimatedCost: estimatedCost.isEmpty ? nil : KotlinDouble(double: Double(estimatedCost) ?? 0.0),
                contractorId: nil,
                templateId: nil
            )

            viewModel.createTask(request: request) { success in
                if success {
                    // Track task creation
                    AnalyticsManager.shared.track(.taskCreated(residenceId: actualResidenceId))
                    // View will dismiss automatically via onChange
                }
            }
        }
    }
}

#Preview("With Residence ID") {
    TaskFormView(residenceId: 1, residences: nil, isPresented: .constant(true))
}

#Preview("With Residence Selection") {
    TaskFormView(residenceId: nil, residences: [], isPresented: .constant(true))
}
