import SwiftUI
import ComposeApp

struct ResidenceDetailView: View {
    let residenceId: Int32

    @StateObject private var viewModel: ResidenceViewModel
    @StateObject private var taskViewModel = TaskViewModel()
    @ObservedObject private var dataManager = DataManagerObservable.shared

    /// Default init used by the app. `onAppear` calls
    /// `getResidence(id:)` which populates `selectedResidence` via
    /// APILayer.
    init(residenceId: Int32) {
        self.residenceId = residenceId
        self._viewModel = StateObject(wrappedValue: ResidenceViewModel())
    }

    /// Snapshot-test / preview init that pre-seeds the VM's
    /// `selectedResidence` by looking up `residenceId` in the
    /// fixture-seeded `DataManagerObservable` cache, so detail state
    /// renders on the first composition frame.
    init(residenceId: Int32, preview _: Bool) {
        self.residenceId = residenceId
        self._viewModel = StateObject(wrappedValue: ResidenceViewModel(
            initialSelectedResidenceId: residenceId
        ))
    }

    // Use TaskViewModel's state instead of local state
    private var tasksResponse: TaskColumnsResponse? { taskViewModel.tasksResponse }
    private var isLoadingTasks: Bool { taskViewModel.isLoadingTasks }
    private var tasksError: String? { taskViewModel.tasksError }

    @State private var contractors: [ContractorSummary] = []
    @State private var isLoadingContractors = false
    @State private var contractorsError: String?

    @State private var showAddTask = false
    @State private var showEditResidence = false
    @State private var showManageUsers = false
    @State private var selectedTaskForEdit: TaskResponse?
    @State private var selectedTaskForComplete: TaskResponse?
    @State private var selectedTaskForArchive: TaskResponse?
    @State private var showArchiveConfirmation = false
    @State private var selectedTaskForCancel: TaskResponse?
    @State private var showCancelConfirmation = false

    // Completion animation state
    @StateObject private var animationPreference = AnimationPreference.shared
    @State private var animatingTaskId: Int32? = nil
    @State private var animationPhase: AnimationPhase = .idle
    @State private var pendingCompletedTask: TaskResponse? = nil
    @Environment(\.accessibilityReduceMotion) private var reduceMotion

    @State private var hasAppeared = false
    @State private var showReportAlert = false
    @State private var showReportConfirmation = false
    @State private var showDeleteConfirmation = false
    @State private var isDeleting = false
    @State private var showingUpgradePrompt = false
    @State private var upgradeTriggerKey = ""
    @StateObject private var subscriptionCache = SubscriptionCacheWrapper.shared

    @Environment(\.dismiss) private var dismiss

    // Check if current user is the owner of the residence
    private func isCurrentUserOwner(of residence: ResidenceResponse) -> Bool {
        guard let currentUser = dataManager.currentUser else {
            return false
        }
        return Int(residence.ownerId) == Int(currentUser.id)
    }

    var body: some View {
        ZStack {
            WarmGradientBackground()

            mainContent
        }
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            leadingToolbar
            trailingToolbar
        }

        // MARK: Alerts
        .alert(L10n.Residences.generateReport, isPresented: $showReportConfirmation) {
            Button(L10n.Common.cancel, role: .cancel) {
                showReportConfirmation = false
            }
            Button(L10n.Residences.generate) {
                viewModel.generateTasksReport(residenceId: residenceId, email: "")
                showReportConfirmation = false
            }
        } message: {
            Text(L10n.Residences.generateReportMessage)
        }

        .alert(L10n.Residences.deleteTitle, isPresented: $showDeleteConfirmation) {
            Button(L10n.Common.cancel, role: .cancel) { }
                .accessibilityIdentifier(AccessibilityIdentifiers.Alert.cancelButton)
            Button(L10n.Common.delete, role: .destructive) {
                deleteResidence()
            }
            .accessibilityIdentifier(AccessibilityIdentifiers.Alert.deleteButton)
        } message: {
            if let residence = viewModel.selectedResidence {
                Text("\(L10n.Residences.deleteConfirmMessage)")
            }
        }

        .alert(L10n.Residences.maintenanceReport, isPresented: $showReportAlert) {
            Button(L10n.Common.ok, role: .cancel) { }
        } message: {
            Text(viewModel.reportMessage ?? "")
        }
        
        // MARK: Sheets
        .sheet(isPresented: $showAddTask) {
            AddTaskView(residenceId: residenceId, isPresented: $showAddTask)
        }
        .sheet(isPresented: $showEditResidence) {
            if let residence = viewModel.selectedResidence {
                EditResidenceView(residence: residence, isPresented: $showEditResidence)
            }
        }
        .sheet(item: $selectedTaskForEdit, onDismiss: {
            loadResidenceTasks(forceRefresh: true)
        }) { task in
            EditTaskView(task: task, isPresented: Binding(
                get: { selectedTaskForEdit != nil },
                set: { if !$0 { selectedTaskForEdit = nil } }
            ))
        }
        .sheet(item: $selectedTaskForComplete, onDismiss: {
            if let task = pendingCompletedTask {
                startCompletionAnimation(for: task)
            } else {
                taskViewModel.isAnimatingCompletion = false
                loadResidenceTasks(forceRefresh: true)
            }
        }) { task in
            CompleteTaskView(task: task) { updatedTask in
                if let updatedTask = updatedTask {
                    pendingCompletedTask = updatedTask
                }
                selectedTaskForComplete = nil
            }
        }
        .sheet(isPresented: $showManageUsers) {
            if let residence = viewModel.selectedResidence {
                ManageUsersView(
                    residenceId: residence.id,
                    residenceName: residence.name,
                    isPrimaryOwner: isCurrentUserOwner(of: residence),
                    residenceOwnerId: residence.ownerId,
                    residence: residence
                )
            }
        }

        .alert("Archive Task", isPresented: $showArchiveConfirmation) {
            Button("Cancel", role: .cancel) {
                selectedTaskForArchive = nil
            }
            Button("Archive", role: .destructive) {
                if let task = selectedTaskForArchive {
                    taskViewModel.archiveTask(id: task.id) { _ in
                        loadResidenceTasks()
                    }
                    selectedTaskForArchive = nil
                }
            }
        } message: {
            if let task = selectedTaskForArchive {
                Text("Are you sure you want to archive \"\(task.title)\"? You can unarchive it later from archived tasks.")
            }
        }
        .alert(L10n.Tasks.cancelTask, isPresented: $showCancelConfirmation) {
            Button(L10n.Common.no, role: .cancel) {
                selectedTaskForCancel = nil
            }
            Button(L10n.Common.yes, role: .destructive) {
                if let task = selectedTaskForCancel {
                    taskViewModel.cancelTask(id: task.id) { _ in
                        loadResidenceTasks()
                    }
                    selectedTaskForCancel = nil
                }
            }
        } message: {
            Text(L10n.Tasks.cancelConfirm)
        }
        .sheet(isPresented: $showingUpgradePrompt) {
            UpgradePromptView(triggerKey: upgradeTriggerKey.isEmpty ? "add_11th_task" : upgradeTriggerKey, isPresented: $showingUpgradePrompt)
        }

        // MARK: onChange & lifecycle
        .onChange(of: viewModel.reportMessage) { _, message in
            if message != nil {
                showReportAlert = true
            }
        }
        .onChange(of: viewModel.selectedResidence) { _, residence in
            if residence != nil {
                hasAppeared = true
            }
        }
        .onChange(of: showAddTask) { _, isShowing in
            if !isShowing {
                loadResidenceTasks(forceRefresh: true)
            }
        }
        .onChange(of: showEditResidence) { _, isShowing in
            if !isShowing {
                loadResidenceData()
            }
        }
        .onAppear {
            loadResidenceData()
        }
        .handleErrors(
            error: viewModel.errorMessage,
            onRetry: { loadResidenceData() }
        )
    }
}

// MARK: - Main Content

private extension ResidenceDetailView {
    @ViewBuilder
    var mainContent: some View {
        // Prefer the cached residence over the loading state: if
        // `selectedResidence` is populated (including from a pre-seeded
        // VM in snapshot tests/previews), render the content even while
        // a background refresh is in flight.
        if let residence = viewModel.selectedResidence {
            contentView(for: residence)
        } else if !hasAppeared || viewModel.isLoading {
            loadingView
        }
    }
    
    var loadingView: some View {
        StandardLoadingView(message: L10n.Residences.loadingResidence)
    }
    
    @ViewBuilder
    func contentView(for residence: ResidenceResponse) -> some View {
        ScrollView(showsIndicators: false) {
            VStack(spacing: OrganicSpacing.comfortable) {
                PropertyHeaderCard(residence: residence)
                    .padding(.horizontal, 16)
                    .padding(.top, 8)

                tasksSection
                    .padding(.horizontal, 16)

                contractorsSection
                    .padding(.horizontal, 16)

                // Honeycomb completion summary
                if let summary = residence.completionSummary {
                    HoneycombSummaryView(
                        summary: summary,
                        residenceName: residence.name
                    )
                    .padding(.horizontal, 16)
                }
            }
            .padding(.bottom, OrganicSpacing.airy)
        }
    }
    
    @ViewBuilder
    var tasksSection: some View {
        if let tasksResponse = tasksResponse {
            TasksSectionContainer(
                tasksResponse: tasksResponse,
                taskViewModel: taskViewModel,
                selectedTaskForEdit: $selectedTaskForEdit,
                selectedTaskForComplete: $selectedTaskForComplete,
                selectedTaskForArchive: $selectedTaskForArchive,
                showArchiveConfirmation: $showArchiveConfirmation,
                selectedTaskForCancel: $selectedTaskForCancel,
                showCancelConfirmation: $showCancelConfirmation,
                animatingTaskId: animatingTaskId,
                animationPhase: animationPhase,
                animationType: animationPreference.selectedAnimation,
                reloadTasks: { loadResidenceTasks(forceRefresh: true) }
            )
        } else if isLoadingTasks {
            ProgressView(L10n.Residences.loadingTasks)
        } else if let tasksError = tasksError {
            Text("\(L10n.Residences.errorLoadingTasks): \(tasksError)")
                .foregroundColor(Color.appError)
                .padding()
        }
    }

    @ViewBuilder
    var contractorsSection: some View {
        VStack(alignment: .leading, spacing: 16) {
            // Section Header
            HStack(alignment: .center, spacing: 12) {
                ZStack {
                    Circle()
                        .fill(Color.appPrimary.opacity(0.12))
                        .frame(width: 40, height: 40)

                    Image(systemName: "person.2.fill")
                        .font(.system(size: 16, weight: .semibold))
                        .foregroundColor(Color.appPrimary)
                }

                Text(L10n.Residences.contractors)
                    .font(.system(size: 20, weight: .bold, design: .rounded))
                    .foregroundColor(Color.appTextPrimary)
                    .accessibilityAddTraits(.isHeader)

                Spacer()
            }
            .padding(.top, 8)

            if isLoadingContractors {
                HStack {
                    Spacer()
                    ProgressView()
                        .tint(Color.appPrimary)
                    Spacer()
                }
                .padding(OrganicSpacing.cozy)
            } else if let error = contractorsError {
                Text("\(L10n.Common.error): \(error)")
                    .foregroundColor(Color.appError)
                    .padding()
            } else if contractors.isEmpty {
                // Empty state with organic styling
                OrganicEmptyState(
                    icon: "person.crop.circle.badge.plus",
                    title: L10n.Residences.noContractors,
                    subtitle: L10n.Residences.addContractorsPrompt,
                    blobVariation: 1
                )
            } else {
                // Contractors list
                VStack(spacing: 12) {
                    ForEach(contractors, id: \.id) { contractor in
                        NavigationLink(destination: ContractorDetailView(contractorId: contractor.id)) {
                            ContractorCard(
                                contractor: contractor,
                                onToggleFavorite: {
                                    // Could implement toggle favorite here if needed
                                }
                            )
                        }
                        .buttonStyle(OrganicCardButtonStyle())
                    }
                }
            }
        }
    }
}

// MARK: - Toolbars

private extension ResidenceDetailView {
    @ToolbarContentBuilder
    var leadingToolbar: some ToolbarContent {
        ToolbarItem(placement: .navigationBarLeading) {
            if viewModel.selectedResidence != nil {
                Button(L10n.Common.edit) {
                    showEditResidence = true
                }
                .accessibilityIdentifier(AccessibilityIdentifiers.Residence.editButton)
                .accessibilityLabel("Edit property")
            }
        }
    }

    @ToolbarContentBuilder
    var trailingToolbar: some ToolbarContent {
        ToolbarItemGroup(placement: .navigationBarTrailing) {
            if viewModel.selectedResidence != nil {
                Button {
                    showReportConfirmation = true
                } label: {
                    if viewModel.isGeneratingReport {
                        ProgressView()
                    } else {
                        Image(systemName: "doc.text")
                    }
                }
                .disabled(viewModel.isGeneratingReport)
                .accessibilityLabel("Generate maintenance report")
            }

            // Manage Users button (owner only) - includes share code generation and easy share
            if let residence = viewModel.selectedResidence, isCurrentUserOwner(of: residence) {
                Button {
                    if subscriptionCache.canShareResidence() {
                        showManageUsers = true
                    } else {
                        upgradeTriggerKey = "share_residence"
                        showingUpgradePrompt = true
                    }
                } label: {
                    Image(systemName: "person.2")
                }
                .accessibilityLabel("Manage users")
            }

            Button {
                // Check LIVE task count before adding
                let totalTasks = tasksResponse?.columns.reduce(0) { $0 + $1.tasks.count } ?? 0
                if subscriptionCache.shouldShowUpgradePrompt(currentCount: totalTasks, limitKey: "tasks") {
                    upgradeTriggerKey = "add_11th_task"
                    showingUpgradePrompt = true
                } else {
                    showAddTask = true
                }
            } label: {
                Image(systemName: "plus")
            }
            .accessibilityIdentifier(AccessibilityIdentifiers.Task.addButton)
            .accessibilityLabel("Add task")

            if let residence = viewModel.selectedResidence, isCurrentUserOwner(of: residence) {
                Button {
                    showDeleteConfirmation = true
                } label: {
                    Image(systemName: "trash")
                        .foregroundStyle(Color.appError)
                }
                .accessibilityIdentifier(AccessibilityIdentifiers.Residence.deleteButton)
                .accessibilityLabel("Delete property")
            }
        }
    }
}

// MARK: - Data Loading

private extension ResidenceDetailView {
    func loadResidenceData() {
        viewModel.getResidence(id: residenceId)
        loadResidenceTasks()
        loadResidenceContractors()
    }
    
    func loadResidenceTasks(forceRefresh: Bool = false) {
        taskViewModel.loadTasks(residenceId: residenceId, forceRefresh: forceRefresh)
    }

    func updateTaskInKanban(_ updatedTask: TaskResponse) {
        taskViewModel.updateTaskInKanban(updatedTask)
    }

    func startCompletionAnimation(for updatedTask: TaskResponse) {
        let duration = animationPreference.animationDuration(reduceMotion: reduceMotion)

        guard duration > 0 else {
            taskViewModel.isAnimatingCompletion = false
            updateTaskInKanban(updatedTask)
            pendingCompletedTask = nil
            return
        }

        animatingTaskId = updatedTask.id

        withAnimation {
            animationPhase = .exiting
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
            withAnimation {
                animationPhase = .complete
            }
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + duration) {
            taskViewModel.isAnimatingCompletion = false
            updateTaskInKanban(updatedTask)
            animatingTaskId = nil
            animationPhase = .idle
            pendingCompletedTask = nil
        }
    }

    // FIX_SKIPPED: LE-3 — deleteResidence() calls APILayer.shared.deleteResidence() directly
    // from the view. ResidenceViewModel does not expose a delete method. Fixing requires adding
    // deleteResidence() to the shared ViewModel layer — architectural refactor deferred.
    func deleteResidence() {
        guard TokenStorage.shared.getToken() != nil else { return }

        isDeleting = true

        Task {
            do {
                let result = try await APILayer.shared.deleteResidence(
                    id: Int32(Int(residenceId))
                )

                await MainActor.run {
                    self.isDeleting = false

                    if result is ApiResultSuccess<KotlinUnit> {
                        dismiss()
                    } else if let errorResult = ApiResultBridge.error(from: result) {
                        self.viewModel.errorMessage = ErrorMessageParser.parse(errorResult.message)
                    } else {
                        self.viewModel.errorMessage = "Failed to delete residence"
                    }
                }
            } catch {
                await MainActor.run {
                    self.isDeleting = false
                    self.viewModel.errorMessage = ErrorMessageParser.parse(error.localizedDescription)
                }
            }
        }
    }

    func loadResidenceContractors() {
        guard TokenStorage.shared.getToken() != nil else { return }

        isLoadingContractors = true
        contractorsError = nil

        Task {
            do {
                let result = try await APILayer.shared.getContractorsByResidence(
                    residenceId: Int32(Int(residenceId)),
                    forceRefresh: false
                )

                await MainActor.run {
                    if let successResult = result as? ApiResultSuccess<NSArray> {
                        self.contractors = (successResult.data as? [ContractorSummary]) ?? []
                        self.isLoadingContractors = false
                    } else if let errorResult = ApiResultBridge.error(from: result) {
                        self.contractorsError = errorResult.message
                        self.isLoadingContractors = false
                    } else {
                        self.contractorsError = "Failed to load contractors"
                        self.isLoadingContractors = false
                    }
                }
            } catch {
                await MainActor.run {
                    self.contractorsError = ErrorMessageParser.parse(error.localizedDescription)
                    self.isLoadingContractors = false
                }
            }
        }
    }
}

private struct TasksSectionContainer: View {
    let tasksResponse: TaskColumnsResponse

    @ObservedObject var taskViewModel: TaskViewModel
    @Binding var selectedTaskForEdit: TaskResponse?
    @Binding var selectedTaskForComplete: TaskResponse?
    @Binding var selectedTaskForArchive: TaskResponse?
    @Binding var showArchiveConfirmation: Bool
    @Binding var selectedTaskForCancel: TaskResponse?
    @Binding var showCancelConfirmation: Bool

    // Completion animation state
    var animatingTaskId: Int32? = nil
    var animationPhase: AnimationPhase = .idle
    var animationType: TaskAnimationType = .none

    let reloadTasks: () -> Void

    var body: some View {
        TasksSection(
            tasksResponse: tasksResponse,
            onEditTask: { task in
                selectedTaskForEdit = task
            },
            onCancelTask: { task in
                selectedTaskForCancel = task
                showCancelConfirmation = true
            },
            onUncancelTask: { taskId in
                taskViewModel.uncancelTask(id: taskId) { _ in
                    reloadTasks()
                }
            },
            onMarkInProgress: { taskId in
                taskViewModel.markInProgress(id: taskId) { success in
                    if success {
                        reloadTasks()
                    }
                }
            },
            onCompleteTask: { task in
                taskViewModel.isAnimatingCompletion = true
                selectedTaskForComplete = task
            },
            onArchiveTask: { task in
                selectedTaskForArchive = task
                showArchiveConfirmation = true
            },
            onUnarchiveTask: { taskId in
                taskViewModel.unarchiveTask(id: taskId) { _ in
                    reloadTasks()
                }
            },
            animatingTaskId: animatingTaskId,
            animationPhase: animationPhase,
            animationType: animationType
        )
    }
}


// MARK: - Preview

struct ResidenceDetailView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            ResidenceDetailView(residenceId: 1)
        }
    }
}
