//
//  WriteOffListView.swift
//  suixinkan
//
//  Created by Codex on 2026/6/29.
//

import SwiftUI

/// 核销管理独立页，对齐 Android WriteOffListScreen。
struct WriteOffListView: View {
    @EnvironmentObject private var accountContext: AccountContext
    @EnvironmentObject private var appRouter: AppRouter
    @Environment(\.ordersAPI) private var ordersAPI
    @EnvironmentObject private var toastCenter: ToastCenter
    @Environment(\.globalLoading) private var globalLoading
    @Environment(\.openURL) private var openURL
    @Environment(\.dismiss) private var dismiss

    @StateObject private var viewModel = WriteOffListViewModel()

    @State private var manualOrderNumber = ""
    @State private var showScanner = false
    @State private var showVerifyConfirmation = false
    @State private var pendingVerifyOrderNumber: String?
    @State private var matchedScannedOrderNumber: String?
    @State private var showStartDateSheet = false
    @State private var showEndDateSheet = false
    @State private var appliedSearchQuery = ""

    private var currentScenicId: Int? { accountContext.currentScenic?.id }
    private var currentStoreId: Int? { accountContext.currentStore?.id }

    var body: some View {
        Group {
            if currentScenicId == nil {
                AppContentUnavailableView("缺少经营上下文", systemImage: "mountain.2")
            } else {
                listContent
            }
        }
        .background(AppDesign.orderPageBackground.ignoresSafeArea())
        .navigationTitle("核销管理")
        .navigationBarTitleDisplayMode(.inline)
        .searchable(text: $viewModel.searchPhone, prompt: "搜索手机号")
        .onSubmit(of: .search) {
            appliedSearchQuery = OrderListSearchBehavior.normalized(viewModel.searchPhone)
            Task { await reload() }
        }
        .onChange(of: viewModel.searchPhone) { newValue in
            guard OrderListSearchBehavior.shouldReloadAfterClear(newText: newValue, appliedQuery: appliedSearchQuery) else { return }
            appliedSearchQuery = ""
            Task { await reload() }
        }
        .task {
            await reload()
            await consumePendingScanCodeIfNeeded()
        }
        .onChange(of: appRouter.pendingOrderScanCode) { _ in
            Task { await consumePendingScanCodeIfNeeded() }
        }
        .fullScreenCover(isPresented: $showScanner) {
            OrderScannerPage(
                onClose: { showScanner = false },
                onSuccess: { rawCode in
                    showScanner = false
                    handleScanResult(rawCode)
                },
                onFailure: { error in
                    showScanner = false
                    toastCenter.show(error.localizedDescription)
                }
            )
        }
        .confirmationDialog("确认核销该订单？", isPresented: $showVerifyConfirmation, titleVisibility: .visible) {
            Button("确认核销") {
                guard let orderNumber = pendingVerifyOrderNumber else { return }
                Task { await verify(orderNumber: orderNumber) }
            }
            Button("取消", role: .cancel) {
                pendingVerifyOrderNumber = nil
            }
        }
        .sheet(isPresented: $showStartDateSheet) {
            singleDateSheet(title: "开始时间", date: viewModel.filterStartDate) { date in
                viewModel.filterStartDate = date
                Task { await reload() }
            }
        }
        .sheet(isPresented: $showEndDateSheet) {
            singleDateSheet(title: "结束时间", date: viewModel.filterEndDate) { date in
                viewModel.filterEndDate = date
                Task { await reload() }
            }
        }
    }

    private var listContent: some View {
        ScrollViewReader { scrollProxy in
            ScrollView {
                VStack(spacing: 12) {
                    WriteOffStatusTabBar(
                        filters: OrderFilters.writeOffStatusFilters,
                        selectedStatus: viewModel.selectedStatus,
                        onSelect: { status in
                            viewModel.selectedStatus = status
                            Task { await reload() }
                        }
                    )
                    dateFilterSection

                    if viewModel.loading && viewModel.orders.isEmpty {
                        ProgressView().frame(maxWidth: .infinity).padding(.vertical, 40)
                    } else if viewModel.orders.isEmpty {
                        AppContentUnavailableView("暂无核销订单", systemImage: "tray")
                            .frame(minHeight: 220)
                    } else {
                        ForEach(viewModel.orders) { item in
                            writeOffCard(item)
                                .id(item.orderNumber)
                                .onAppear {
                                    guard item.id == viewModel.orders.last?.id else { return }
                                    Task { await loadMore() }
                                }
                        }
                        if viewModel.loadingMore {
                            ProgressView().frame(maxWidth: .infinity)
                        }
                    }
                }
                .padding(.bottom, 16)
            }
            .onChange(of: matchedScannedOrderNumber) { orderNumber in
                guard let orderNumber else { return }
                withAnimation(.easeInOut(duration: 0.25)) {
                    scrollProxy.scrollTo(orderNumber, anchor: .center)
                }
            }
        }
        .refreshable { await reload(showLoading: false) }
    }

    private var dateFilterSection: some View {
        HStack(spacing: 8) {
            dateFilterButton(title: "开始时间", date: viewModel.filterStartDate) {
                showStartDateSheet = true
            }
            dateFilterButton(title: "结束时间", date: viewModel.filterEndDate) {
                showEndDateSheet = true
            }
        }
        .padding(.horizontal, 16)
    }

    private func dateFilterButton(title: String, date: Date?, action: @escaping () -> Void) -> some View {
        Button(action: action) {
            HStack {
                Image(systemName: "calendar")
                Text(date.map { OrderDateRangeFormatter.displayText(start: $0, end: nil, placeholder: title) } ?? title)
                    .font(.system(size: 13))
                    .lineLimit(1)
            }
            .foregroundStyle(AppDesign.orderLabelColor)
            .frame(maxWidth: .infinity)
            .frame(height: 35)
            .background(AppDesign.orderInputBackground, in: RoundedRectangle(cornerRadius: 4))
        }
        .buttonStyle(.plain)
    }

    private func writeOffCard(_ item: WriteOffOrderItem) -> some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack {
                Text("订单号：\(item.orderNumber)")
                    .font(.system(size: 14, weight: .semibold))
                Spacer()
                OrderStatusChip(
                    text: viewModel.displayVerificationStatus(for: item),
                    status: viewModel.canVerify(item) ? 18 : 30
                )
            }
            OrderInfoRow(title: "项目名称", value: item.projectName.isEmpty ? "--" : item.projectName)
            OrderInfoRow(title: "手机号", value: item.userPhone.isEmpty ? "--" : item.userPhone) {
                HStack(spacing: 7) {
                    Text(item.userPhone)
                        .font(.system(size: 14, weight: .medium))
                    OrderPhoneCallButton {
                        dialPhone(item.userPhone)
                    }
                }
            }
            OrderInfoRow(title: "订单状态", value: item.orderStatusName.isEmpty ? "--" : item.orderStatusName)
            HStack {
                Text("¥\(item.orderAmount)")
                    .font(.system(size: 18, weight: .bold))
                    .foregroundStyle(AppDesign.primary)
                Spacer()
                Button(viewModel.canVerify(item) ? "核销" : "已处理") {
                    pendingVerifyOrderNumber = item.orderNumber
                    showVerifyConfirmation = true
                }
                .font(.system(size: 14, weight: .semibold))
                .foregroundStyle(.white)
                .padding(.horizontal, 12)
                .frame(height: 32)
                .background(
                    viewModel.canVerify(item) ? AppDesign.primary : Color(hex: 0x9CA3AF),
                    in: RoundedRectangle(cornerRadius: 8)
                )
                .disabled(!viewModel.canVerify(item) || viewModel.isVerifying)
            }
        }
        .padding(15)
        .background(
            matchedScannedOrderNumber == item.orderNumber ? Color(hex: 0xEEF6FF) : .white,
            in: RoundedRectangle(cornerRadius: 12)
        )
        .overlay {
            RoundedRectangle(cornerRadius: 12)
                .stroke(matchedScannedOrderNumber == item.orderNumber ? AppDesign.primary : .clear, lineWidth: 2)
        }
        .padding(.horizontal, 16)
    }

    private func singleDateSheet(title: String, date: Date?, onConfirm: @escaping (Date?) -> Void) -> some View {
        NavigationStack {
            Form {
                DatePicker(title, selection: Binding(
                    get: { date ?? Date() },
                    set: { onConfirm($0) }
                ), displayedComponents: .date)
            }
            .navigationTitle(title)
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("清空") { onConfirm(nil) }
                }
            }
        }
    }

    private func reload(showLoading: Bool = true) async {
        do {
            try await globalLoading.withOptionalLoading(showLoading && viewModel.orders.isEmpty, message: "加载中...") {
                try await viewModel.reload(
                    api: ordersAPI,
                    scenicId: currentScenicId,
                    storeId: currentStoreId,
                    showLoading: showLoading
                )
            }
        } catch {
            toastCenter.show(error.localizedDescription)
        }
    }

    private func loadMore() async {
        do {
            try await viewModel.loadMore(api: ordersAPI, scenicId: currentScenicId, storeId: currentStoreId)
        } catch {
            toastCenter.show(error.localizedDescription)
        }
    }

    private func verify(orderNumber: String) async {
        guard let scenicId = currentScenicId else { return }
        do {
            try await globalLoading.withLoading(message: "核销中...") {
                try await viewModel.verify(
                    api: ordersAPI,
                    scenicId: scenicId,
                    storeId: currentStoreId,
                    orderNumber: orderNumber
                )
            }
            manualOrderNumber = ""
            pendingVerifyOrderNumber = nil
            matchedScannedOrderNumber = nil
            toastCenter.show("核销成功")
        } catch {
            toastCenter.show(error.localizedDescription)
        }
    }

    private func consumePendingScanCodeIfNeeded() async {
        guard let rawCode = appRouter.consumePendingOrderScanCode() else { return }
        handleScanResult(rawCode)
    }

    private func handleScanResult(_ rawCode: String) {
        guard let result = viewModel.matchedWriteOffOrder(for: rawCode) else {
            toastCenter.show("扫码成功，但未识别到有效订单号。")
            return
        }
        manualOrderNumber = result.orderNumber
        pendingVerifyOrderNumber = result.orderNumber
        if let matched = result.matched {
            matchedScannedOrderNumber = matched.orderNumber
        }
        showVerifyConfirmation = true
    }

    private func dialPhone(_ phone: String) {
        let trimmed = phone.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmed.isEmpty, let url = URL(string: "tel:\(trimmed)") else { return }
        openURL(url)
    }
}
