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

import SwiftUI

/// 摄影师/非店长角色的订单 Tab 主列表，对齐 Android OrderListScreen。
struct StoreOrderListView: View {
    @EnvironmentObject private var accountContext: AccountContext
    @EnvironmentObject private var permissionContext: PermissionContext
    @EnvironmentObject private var appRouter: AppRouter
    @EnvironmentObject private var router: RouterPath
    @Environment(\.ordersAPI) private var ordersAPI
    @Environment(\.cooperationOrderAPI) private var cooperationOrderAPI
    @EnvironmentObject private var toastCenter: ToastCenter
    @Environment(\.globalLoading) private var globalLoading
    @Environment(\.openURL) private var openURL

    @StateObject private var viewModel = OrdersViewModel()
    @StateObject private var refundViewModel = OrderRefundViewModel()

    @State private var showDateFilterSheet = false
    @State private var showScanner = false
    @State private var pendingVerifyOrderNumber: String?
    @State private var showVerifyConfirmation = false
    @State private var bindAcquirerSaleUserId: Int?
    @State private var referralBindOrderNumber: String?
    @State private var appliedSearchQuery = ""

    private var currentScenicId: Int? { accountContext.currentScenic?.id }
    private var currentStoreId: Int? { accountContext.currentStore?.id }
    private var currentAppRole: AppRoleCode? { permissionContext.currentAppRole }
    private var hideOrderWriteActions: Bool { OrdersViewModel.isScenicAdminReadOnly(appRole: currentAppRole) }

    var body: some View {
        Group {
            if currentScenicId == nil {
                AppContentUnavailableView(
                    "缺少经营上下文",
                    systemImage: "mountain.2",
                    description: Text("请先在首页选择景区后查看订单。")
                )
            } else {
                orderListContent
            }
        }
        .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() }
        .onChange(of: accountContext.currentScenic?.id) { _ in
            Task { await reload() }
        }
        .sheet(isPresented: $showDateFilterSheet) {
            DateRangePickerSheet(
                initialStartDate: viewModel.filterStartDate,
                initialEndDate: viewModel.filterEndDate
            ) { start, end in
                viewModel.filterStartDate = start
                viewModel.filterEndDate = end
                Task { await reload() }
            }
        }
        .sheet(item: refundOrderBinding) { order in
            OrderRefundDialogView(
                viewModel: refundViewModel,
                order: order,
                onDismiss: { viewModel.refundingOrder = nil },
                onSuccess: {
                    viewModel.refundingOrder = nil
                    toastCenter.show("退款申请已提交")
                    Task { await reload(showLoading: false) }
                }
            )
        }
        .sheet(item: sendGiftBinding) { context in
            SendGiftDialogView(
                context: context,
                onDismiss: { viewModel.sendGiftContext = nil },
                onConfirm: { photo, video in
                    Task {
                        do {
                            try await viewModel.submitSendGift(
                                api: ordersAPI,
                                scenicId: currentScenicId,
                                appRole: currentAppRole,
                                photoNum: photo,
                                videoNum: video
                            )
                            toastCenter.show("赠送成功")
                        } catch {
                            toastCenter.show(error.localizedDescription)
                        }
                    }
                }
            )
        }
        .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: $showCancelConfirmation, titleVisibility: .visible) {
            Button("确认取消", role: .destructive) {
                guard let orderNumber = pendingCancelOrderNumber else { return }
                Task {
                    do {
                        try await viewModel.cancelOrder(
                            api: ordersAPI,
                            scenicId: currentScenicId,
                            appRole: currentAppRole,
                            orderNumber: orderNumber
                        )
                        pendingCancelOrderNumber = nil
                        toastCenter.show("订单已取消")
                    } catch {
                        toastCenter.show(error.localizedDescription)
                    }
                }
            }
            Button("取消", role: .cancel) { pendingCancelOrderNumber = nil }
        }
        .confirmationDialog("确认核销该订单？", isPresented: $showVerifyConfirmation, titleVisibility: .visible) {
            Button("确认核销") {
                guard let orderNumber = pendingVerifyOrderNumber else { return }
                Task { await verify(orderNumber: orderNumber) }
            }
            Button("取消", role: .cancel) { pendingVerifyOrderNumber = nil }
        }
        .fullScreenCover(item: bindAcquirerBinding) { item in
            NavigationStack {
                BindAcquirerView(saleUserId: item.saleUserId, onSuccess: {
                    bindAcquirerSaleUserId = nil
                })
            }
        }
        .appNavigationDestination(item: referralBindBinding) { item in
            ReferralOrderSelectView(orderNumber: item.orderNumber) {
                Task { await reload(showLoading: false) }
            }
        }
    }

    @State private var pendingCancelOrderNumber: String?
    @State private var showCancelConfirmation = false

    private var orderListContent: some View {
        ScrollView {
            LazyVStack(spacing: 0, pinnedViews: [.sectionHeaders]) {
                Section {
                    LazyVStack(spacing: 12) {
                        if viewModel.loading && viewModel.storeOrders.isEmpty {
                            ProgressView().frame(maxWidth: .infinity).padding(.vertical, 40)
                        } else if viewModel.storeOrders.isEmpty {
                            AppContentUnavailableView("暂无订单", systemImage: "tray", description: Text("可切换筛选条件或下拉刷新。"))
                                .frame(minHeight: 260)
                        } else {
                            ForEach(viewModel.storeOrders) { item in
                                OrderListCardView(
                                    item: item,
                                    hideOrderWriteActions: hideOrderWriteActions,
                                    showOrderSource: viewModel.shouldShowOrderSource(order: item, appRole: currentAppRole),
                                    sourceSelection: viewModel.getOrderSourceSelection(for: item),
                                    orderSourcePeople: viewModel.orderSourcePeople,
                                    leadsForPerson: { person in
                                        viewModel.orderSourceLeads[person.key] ?? []
                                    },
                                    leadsLoading: viewModel.loadingOrderSourceLeadsFor != nil,
                                    onRefund: {
                                        refundViewModel.begin(item: item)
                                        viewModel.refundingOrder = item
                                    },
                                    onVerify: {
                                        pendingVerifyOrderNumber = item.orderNumber
                                        showScanner = true
                                    },
                                    onUploadTask: {
                                        router.navigate(to: .orders(.multiTravelTaskUpload(orderNumber: item.orderNumber)))
                                    },
                                    onRefinedChange: { value in
                                        Task {
                                            do {
                                                try await viewModel.updateRefinedChoice(
                                                    api: ordersAPI,
                                                    orderNumber: item.orderNumber,
                                                    isRefined: value
                                                )
                                            } catch {
                                                toastCenter.show(error.localizedDescription)
                                            }
                                        }
                                    },
                                    onSendGift: { viewModel.prepareSendGift(for: item) },
                                    onCancelOrder: {
                                        pendingCancelOrderNumber = item.orderNumber
                                        showCancelConfirmation = true
                                    },
                                    onHistoricalPhoto: {
                                        router.navigate(to: .orders(.historicalShooting(orderNumber: item.orderNumber)))
                                    },
                                    onCallPhone: { dialPhone(item.phone) },
                                    onOrderSourceSheetOpen: {
                                        Task {
                                            await viewModel.prepareOrderSourceSheet(
                                                api: cooperationOrderAPI,
                                                storeId: currentStoreId
                                            )
                                        }
                                    },
                                    onOrderSourcePersonClick: { person in
                                        Task {
                                            await viewModel.loadOrderSourceLeads(api: cooperationOrderAPI, person: person)
                                        }
                                    },
                                    onOrderSourceSelectionChange: { selection in
                                        Task {
                                            do {
                                                try await viewModel.bindOrderSource(
                                                    api: cooperationOrderAPI,
                                                    orderNumber: item.orderNumber,
                                                    selection: selection
                                                )
                                                toastCenter.show("绑定成功")
                                                await reload(showLoading: false)
                                            } catch {
                                                toastCenter.show(error.localizedDescription)
                                            }
                                        }
                                    },
                                    callSourcePhone: dialPhone
                                )
                                .onAppear {
                                    guard item.id == viewModel.storeOrders.last?.id else { return }
                                    Task { await loadMore() }
                                }
                            }
                            if viewModel.loadingMore {
                                ProgressView().frame(maxWidth: .infinity).padding(.vertical, 8)
                            }
                        }
                    }
                    .padding(.horizontal, 16)
                    .padding(.bottom, 16)
                } header: {
                    OrderListHeaderView(
                        filterTitle: viewModel.currentFilterTitle,
                        timeFilterTitle: OrderDateRangeFormatter.displayText(
                            start: viewModel.filterStartDate,
                            end: viewModel.filterEndDate
                        ),
                        statusFilters: OrderFilters.statusFilters,
                        selectedStatus: viewModel.selectedStatus,
                        onStatusSelected: { status in
                            viewModel.selectedStatus = status
                            Task { await reload() }
                        },
                        onTimeFilterTap: { showDateFilterSheet = true }
                    )
                }
            }
        }
        .refreshable { await reload(showLoading: false) }
    }

    private var refundOrderBinding: Binding<OrderEntity?> {
        Binding(
            get: { viewModel.refundingOrder },
            set: { viewModel.refundingOrder = $0 }
        )
    }

    private var sendGiftBinding: Binding<OrdersViewModel.SendGiftContext?> {
        Binding(
            get: { viewModel.sendGiftContext },
            set: { viewModel.sendGiftContext = $0 }
        )
    }

    private var bindAcquirerBinding: Binding<BindAcquirerSheetItem?> {
        Binding(
            get: { bindAcquirerSaleUserId.map(BindAcquirerSheetItem.init(saleUserId:)) },
            set: { bindAcquirerSaleUserId = $0?.saleUserId }
        )
    }

    private var referralBindBinding: Binding<OrderNumberSheetItem?> {
        Binding(
            get: { referralBindOrderNumber.map(OrderNumberSheetItem.init(orderNumber:)) },
            set: { referralBindOrderNumber = $0?.orderNumber }
        )
    }

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

    private func loadMore() async {
        do {
            try await viewModel.loadMoreStoreOrders(
                api: ordersAPI,
                scenicId: currentScenicId,
                appRole: currentAppRole
            )
        } 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
                )
            }
            pendingVerifyOrderNumber = nil
            toastCenter.show("核销成功")
        } catch {
            toastCenter.show(error.localizedDescription)
        }
    }

    private func handleScanResult(_ rawCode: String) {
        if SaleUserQrParser.isSaleUserBindQR(rawCode) {
            guard let saleUserId = SaleUserQrParser.parseSaleUserId(rawCode), saleUserId > 0 else {
                toastCenter.show("请扫描正确的获客员二维码")
                return
            }
            bindAcquirerSaleUserId = saleUserId
            return
        }

        guard let orderNumber = OrderNumberParser.parse(rawCode) else {
            toastCenter.show("扫码成功，但未识别到有效订单号。")
            return
        }
        pendingVerifyOrderNumber = 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)
    }
}
