//
//  PaymentCollectionView.swift
//  suixinkan
//
//  Created by Codex on 2026/6/22.
//

import AVFoundation
import Photos
import SwiftUI

/// 收款页，展示静态收款码、动态金额收款和收款记录入口。
struct PaymentCollectionView: View {
    @EnvironmentObject private var accountContext: AccountContext
    @Environment(\.paymentAPI) private var paymentAPI
    @EnvironmentObject private var toastCenter: ToastCenter
    @Environment(\.globalLoading) private var globalLoading

    @StateObject private var viewModel = PaymentCollectionViewModel()
    @State private var showingAmountDialog = false
    @State private var pollingTask: Task<Void, Never>?

    private var scenicName: String {
        accountContext.currentScenic?.name ?? "暂无景区"
    }

    private var staffID: String {
        accountContext.profile?.userId ?? ""
    }

    var body: some View {
        ScrollView {
            VStack(spacing: AppMetrics.Spacing.medium) {
                PaymentQRSection(
                    scenicName: scenicName,
                    qrImage: viewModel.qrImage,
                    paymentSuccessData: viewModel.paymentSuccessData,
                    onSetAmount: openAmountDialog,
                    onSaveQRCode: saveQRCode,
                    onRefresh: refreshPayCode
                )

                PaymentStatusSection(
                    scanSuccessTime: viewModel.scanSuccessTime,
                    paymentSuccessData: viewModel.paymentSuccessData
                )

                infoCard

                NavigationLink {
                    PaymentCollectionRecordView()
                } label: {
                    PaymentNavigationRow(title: "收款记录")
                }
                .buttonStyle(.plain)

                voiceToggleRow

                if case .failed(let message) = viewModel.status {
                    PaymentWhiteCard {
                        Text(message)
                            .font(.system(size: AppMetrics.FontSize.subheadline))
                            .foregroundStyle(AppDesign.warning)
                            .frame(maxWidth: .infinity, alignment: .leading)
                    }
                }
            }
            .padding(.horizontal, AppMetrics.Spacing.pageHorizontal)
            .padding(.vertical, AppMetrics.Spacing.medium)
        }
        .background(Self.pageBackground)
        .navigationTitle("收款详情")
        .navigationBarTitleDisplayMode(.inline)
        .overlay {
            if showingAmountDialog {
                PaymentSetAmountDialog(
                    amountText: $viewModel.amountText,
                    remarkText: $viewModel.remarkText,
                    canConfirm: viewModel.canConfirmAmount,
                    onConfirm: confirmAmount,
                    onDismiss: { showingAmountDialog = false }
                )
            }
        }
        .task(id: accountContext.currentScenic?.id) {
            await globalLoading.withOptionalLoading(viewModel.qrImage == nil, message: "加载中...") {
                await viewModel.loadPayCode(api: paymentAPI, scenicId: accountContext.currentScenic?.id)
            }
        }
        .onDisappear {
            pollingTask?.cancel()
        }
        .onChange(of: viewModel.errorMessage) { message in
            if let message {
                toastCenter.show(message)
            }
        }
    }

    /// 景区/收款方/员工信息卡。
    private var infoCard: some View {
        PaymentWhiteCard {
            VStack(spacing: 6) {
                PaymentInfoRow(label: "景区名称", value: scenicName)
                PaymentInfoRow(label: "收款方", value: PaymentMerchantInfo.payeeCompany)
                PaymentInfoRow(label: "员工ID", value: staffID)
            }
        }
    }

    /// 收款到账语音提醒开关行。
    private var voiceToggleRow: some View {
        HStack {
            Text("收款到账语音提醒")
                .font(.system(size: AppMetrics.FontSize.subheadline))
                .foregroundStyle(AppDesign.orderLabelColor)
            Spacer()
            Toggle("", isOn: Binding(
                get: { viewModel.isVoiceBroadcast },
                set: { _ in viewModel.toggleVoiceBroadcast() }
            ))
            .labelsHidden()
        }
        .frame(height: 52)
        .padding(.horizontal, AppMetrics.Spacing.medium)
        .background(.white, in: RoundedRectangle(cornerRadius: 12))
    }

    /// 打开设置金额弹窗。
    private func openAmountDialog() {
        if viewModel.prepareAmountDialog() {
            showingAmountDialog = true
        }
    }

    /// 确认设置金额并启动轮询 fallback。
    private func confirmAmount() {
        if viewModel.confirmAmount() {
            showingAmountDialog = false
            toastCenter.show("金额设置成功，二维码已更新")
            startPolling()
        }
    }

    /// 刷新收款码。
    private func refreshPayCode() {
        Task {
            await globalLoading.withLoading(message: "刷新中...") {
                await viewModel.loadPayCode(api: paymentAPI, scenicId: accountContext.currentScenic?.id)
            }
        }
    }

    /// 启动本次动态收款轮询。
    private func startPolling() {
        pollingTask?.cancel()
        pollingTask = Task {
            await viewModel.primePaymentRecords(api: paymentAPI, scenicId: accountContext.currentScenic?.id)
            await viewModel.pollUntilPaymentDetected(api: paymentAPI, scenicId: accountContext.currentScenic?.id)
        }
    }

    /// 保存当前二维码到系统相册。
    private func saveQRCode() {
        guard viewModel.hasStaticPayCode, let image = viewModel.qrImage else {
            toastCenter.show("请先获取收款码")
            return
        }
        PHPhotoLibrary.requestAuthorization(for: .addOnly) { status in
            guard status == .authorized || status == .limited else {
                Task { @MainActor in toastCenter.show("请允许添加照片权限") }
                return
            }
            PHPhotoLibrary.shared().performChanges {
                PHAssetChangeRequest.creationRequestForAsset(from: image)
            } completionHandler: { success, error in
                Task { @MainActor in
                    toastCenter.show(success ? "保存成功" : (error?.localizedDescription ?? "保存失败"))
                }
            }
        }
    }
}

/// 收款记录页，按日期展示扫码收款明细。
struct PaymentCollectionRecordView: View {
    @EnvironmentObject private var accountContext: AccountContext
    @Environment(\.paymentAPI) private var paymentAPI
    @EnvironmentObject private var toastCenter: ToastCenter
    @Environment(\.globalLoading) private var globalLoading
    @StateObject private var viewModel = PaymentCollectionRecordViewModel()

    var body: some View {
        ScrollView {
            VStack(spacing: AppMetrics.Spacing.medium) {
                if viewModel.groups.isEmpty {
                    PaymentRecordEmptyView()
                } else {
                    PaymentWhiteCard {
                        VStack(spacing: AppMetrics.Spacing.medium) {
                            ForEach(viewModel.groups) { group in
                                VStack(spacing: AppMetrics.Spacing.xSmall) {
                                    PaymentRecordDayHeader(group: group)
                                    ForEach(group.items) { item in
                                        PaymentRecordItemCard(item: item)
                                    }
                                }
                            }
                        }
                    }

                    Text("仅支持查看7天的数据")
                        .font(.system(size: AppMetrics.FontSize.caption))
                        .foregroundStyle(Color(hex: 0xB6BECA))
                        .frame(maxWidth: .infinity)
                        .multilineTextAlignment(.center)
                        .padding(.bottom, AppMetrics.Spacing.medium)
                }
            }
            .padding(.horizontal, AppMetrics.Spacing.pageHorizontal)
            .padding(.top, AppMetrics.Spacing.medium)
        }
        .background(PaymentCollectionView.pageBackground)
        .navigationTitle("收款记录")
        .navigationBarTitleDisplayMode(.inline)
        .refreshable {
            await viewModel.load(api: paymentAPI, scenicId: accountContext.currentScenic?.id)
        }
        .task(id: accountContext.currentScenic?.id) {
            await globalLoading.withOptionalLoading(viewModel.groups.isEmpty, message: "加载中...") {
                await viewModel.load(api: paymentAPI, scenicId: accountContext.currentScenic?.id)
            }
        }
        .onChange(of: viewModel.errorMessage) { message in
            if let message {
                toastCenter.show(message)
            }
        }
    }
}

/// 收款语音播报服务，使用系统 TTS 播报到账提示。
@MainActor
final class PaymentVoiceSpeaker {
    static let shared = PaymentVoiceSpeaker()

    private let synthesizer = AVSpeechSynthesizer()

    private init() {}

    /// 播报指定中文文案。
    func speak(_ text: String) {
        let utterance = AVSpeechUtterance(string: text)
        utterance.voice = AVSpeechSynthesisVoice(language: "zh-CN")
        utterance.rate = 0.5
        synthesizer.speak(utterance)
    }
}
