//
//  ScenicSettlementViews.swift
//  suixinkan
//
//  Created by Codex on 2026/6/25.
//

import SwiftUI

/// 景区结算申请页，支持选择未开通结算的景区并提交金额。
struct ScenicSettlementView: View {
    @EnvironmentObject private var accountContext: AccountContext
    @Environment(\.scenicPermissionAPI) private var scenicPermissionAPI
    @Environment(\.scenicSettlementAPI) private var scenicSettlementAPI
    @EnvironmentObject private var toastCenter: ToastCenter
    @StateObject private var viewModel = ScenicSettlementViewModel()
    @State private var showScenicApplication = false

    var body: some View {
        VStack(spacing: 0) {
            NewScenicBanner {
                showScenicApplication = true
            }
            ScrollView {
                VStack(spacing: AppMetrics.Spacing.small) {
                    existingScenicsSection
                    selectableScenicsSection
                    settlementInfoSection
                }
                .padding(AppMetrics.Spacing.medium)
            }
            submitButton
        }
        .background(Color(hex: 0xF5F7FA).ignoresSafeArea())
        .navigationTitle("景区结算")
        .navigationBarTitleDisplayMode(.inline)
        .task {
            await viewModel.load(api: scenicPermissionAPI, existingScenics: accountContext.scenicScopes)
        }
        .refreshable {
            await viewModel.load(api: scenicPermissionAPI, existingScenics: accountContext.scenicScopes)
        }
        .sheet(isPresented: $showScenicApplication) {
            NavigationStack {
                ScenicApplicationView()
            }
        }
        .onChange(of: viewModel.message) { message in
            guard let message else { return }
            toastCenter.show(message)
            viewModel.message = nil
        }
    }

    private var existingScenicsSection: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.xSmall) {
            Text("已有景区")
                .font(.system(size: AppMetrics.FontSize.subheadline, weight: .semibold))
            if viewModel.existingScenics.isEmpty {
                Text("暂无已开通景区")
                    .font(.system(size: AppMetrics.FontSize.caption))
                    .foregroundStyle(AppDesign.textSecondary)
            } else {
                ForEach(viewModel.existingScenics) { scenic in
                    HStack(spacing: AppMetrics.Spacing.xSmall) {
                        Image(systemName: "checkmark.seal.fill")
                            .foregroundStyle(AppDesign.success)
                        Text(scenic.name)
                            .font(.system(size: AppMetrics.FontSize.footnote))
                            .foregroundStyle(AppDesign.textPrimary)
                        Spacer(minLength: 0)
                    }
                }
            }
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(AppMetrics.Spacing.small)
        .background(.white, in: RoundedRectangle(cornerRadius: 12))
    }

    private var selectableScenicsSection: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.xSmall) {
            HStack {
                Text("可申请结算景区")
                    .font(.system(size: AppMetrics.FontSize.subheadline, weight: .semibold))
                Spacer()
                formBadge("已选 \(viewModel.selectedCount)", tint: viewModel.selectedCount == 0 ? AppDesign.textSecondary : AppDesign.primary)
            }

            if viewModel.isLoading && viewModel.options.isEmpty {
                ProgressView()
                    .frame(maxWidth: .infinity, minHeight: 120)
            } else if viewModel.loadFailed {
                VStack(spacing: AppMetrics.Spacing.xSmall) {
                    AppContentUnavailableView(
                        "可申请景区加载失败",
                        systemImage: "exclamationmark.triangle",
                        description: Text(viewModel.loadFailureReason ?? "请检查网络后重试")
                    )
                    Button("重新加载") {
                        Task { await viewModel.load(api: scenicPermissionAPI, existingScenics: accountContext.scenicScopes) }
                    }
                    .font(.system(size: AppMetrics.FontSize.footnote, weight: .semibold))
                    .buttonStyle(.plain)
                }
                .frame(maxWidth: .infinity, minHeight: 160)
            } else if viewModel.options.isEmpty {
                Text("暂无可申请结算景区")
                    .font(.system(size: AppMetrics.FontSize.caption))
                    .foregroundStyle(AppDesign.textSecondary)
            } else {
                ForEach(viewModel.options) { option in
                    Button {
                        viewModel.toggleScenic(id: option.id)
                    } label: {
                        HStack {
                            Text(option.name)
                                .font(.system(size: AppMetrics.FontSize.footnote))
                                .foregroundStyle(option.selected ? AppDesign.primary : AppDesign.textPrimary)
                            Spacer()
                            Image(systemName: option.selected ? "checkmark.circle.fill" : "circle")
                                .foregroundStyle(option.selected ? AppDesign.primary : Color(hex: 0xCBD5E1))
                        }
                        .padding(.horizontal, AppMetrics.Spacing.small)
                        .padding(.vertical, AppMetrics.Spacing.xSmall)
                        .background(option.selected ? AppDesign.primarySoft : Color(hex: 0xF8FAFC), in: RoundedRectangle(cornerRadius: 8))
                    }
                    .buttonStyle(.plain)
                }
            }
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(AppMetrics.Spacing.small)
        .background(.white, in: RoundedRectangle(cornerRadius: 12))
    }

    private var settlementInfoSection: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.xSmall) {
            HStack {
                Text("结算信息")
                    .font(.system(size: AppMetrics.FontSize.subheadline, weight: .semibold))
                    .foregroundStyle(AppDesign.textPrimary)
                Spacer()
                formBadge("已选 \(viewModel.selectedCount)", tint: viewModel.selectedCount == 0 ? AppDesign.textSecondary : AppDesign.primary)
                formBadge(viewModel.amountValidation.badgeText, tint: viewModel.amountValidation.badgeColor)
            }
            TextField("申请金额（必填）", text: Binding(
                get: { viewModel.amountText },
                set: { viewModel.amountText = $0 }
            ))
            .keyboardType(.decimalPad)
            .textFieldStyle(.plain)
            .padding(.horizontal, AppMetrics.Spacing.small)
            .frame(minHeight: 44)
            .background(Color(hex: 0xF8FAFC), in: RoundedRectangle(cornerRadius: 10))

            TextField("备注信息（可选）", text: Binding(
                get: { viewModel.remarkText },
                set: { viewModel.remarkText = $0 }
            ), axis: .vertical)
            .lineLimit(2...4)
            .textFieldStyle(.plain)
            .padding(AppMetrics.Spacing.small)
            .frame(minHeight: 86, alignment: .topLeading)
            .background(Color(hex: 0xF8FAFC), in: RoundedRectangle(cornerRadius: 10))
        }
        .padding(AppMetrics.Spacing.small)
        .background(.white, in: RoundedRectangle(cornerRadius: 12))
    }

    private var submitButton: some View {
        Button(viewModel.isSubmitting ? "提交中..." : "提交审核") {
            Task { _ = await viewModel.submit(api: scenicSettlementAPI) }
        }
        .font(.system(size: AppMetrics.FontSize.body, weight: .semibold))
        .foregroundStyle(.white)
        .frame(maxWidth: .infinity)
        .frame(height: 48)
        .background(viewModel.canSubmit ? AppDesign.primary : Color(hex: 0xC9CED6), in: RoundedRectangle(cornerRadius: 12))
        .buttonStyle(.plain)
        .disabled(!viewModel.canSubmit)
        .padding(AppMetrics.Spacing.medium)
        .background(.white)
    }

    private func formBadge(_ text: String, tint: Color) -> some View {
        Text(text)
            .font(.system(size: AppMetrics.FontSize.caption, weight: .medium))
            .foregroundStyle(tint)
            .padding(.horizontal, AppMetrics.Spacing.small)
            .frame(height: 22)
            .background(tint.opacity(0.12), in: Capsule())
    }
}

/// 景区结算审核记录页，展示景区申请和权限申请审核状态。
struct ScenicSettlementReviewView: View {
    @Environment(\.scenicPermissionAPI) private var scenicPermissionAPI
    @EnvironmentObject private var toastCenter: ToastCenter
    @StateObject private var viewModel = ScenicSettlementReviewViewModel()

    var body: some View {
        ScrollView {
            VStack(spacing: AppMetrics.Spacing.small) {
                if viewModel.loadFailedAll {
                    fullFailureView
                } else {
                    reviewSummary
                    scenicSection
                    roleSection
                }
            }
            .padding(AppMetrics.Spacing.medium)
        }
        .background(Color(hex: 0xF5F7FA).ignoresSafeArea())
        .navigationTitle("结算审核")
        .navigationBarTitleDisplayMode(.inline)
        .task {
            await viewModel.load(api: scenicPermissionAPI)
        }
        .refreshable {
            await viewModel.load(api: scenicPermissionAPI)
        }
        .onChange(of: viewModel.message) { message in
            guard let message else { return }
            toastCenter.show(message)
            viewModel.message = nil
        }
    }

    private var fullFailureView: some View {
        VStack(spacing: AppMetrics.Spacing.small) {
            AppContentUnavailableView(
                "审核记录加载失败",
                systemImage: "exclamationmark.triangle",
                description: Text("景区申请与权限申请均未加载成功，请检查网络后重试")
            )
            Button("重新加载") {
                Task { await viewModel.load(api: scenicPermissionAPI) }
            }
            .font(.system(size: AppMetrics.FontSize.footnote, weight: .semibold))
            .foregroundStyle(AppDesign.primary)
            .padding(.horizontal, AppMetrics.Spacing.small)
            .frame(height: 34)
            .background(AppDesign.primarySoft, in: RoundedRectangle(cornerRadius: 8))
            .buttonStyle(.plain)
        }
        .frame(maxWidth: .infinity, minHeight: 260)
        .background(.white, in: RoundedRectangle(cornerRadius: 12))
    }

    private var reviewSummary: some View {
        HStack(spacing: AppMetrics.Spacing.xSmall) {
            summaryCard("景区申请", "\(viewModel.scenicApplications.count)")
            summaryCard("权限申请", "\(viewModel.roleApplications.count)")
            summaryCard("待审核", "\(viewModel.pendingCount)")
        }
    }

    private var scenicSection: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.xSmall) {
            sectionHeader("景区申请记录", count: viewModel.scenicApplications.count, icon: "mountain.2.fill")
            if viewModel.scenicLoadFailed {
                sectionFailureRow("景区申请记录加载失败")
            } else if viewModel.scenicApplications.isEmpty {
                Text("暂无景区申请记录")
                    .font(.system(size: AppMetrics.FontSize.caption))
                    .foregroundStyle(AppDesign.textSecondary)
            } else {
                ForEach(viewModel.scenicApplications) { item in
                    reviewRow(
                        title: item.scenicName,
                        code: item.code,
                        subtitle: item.createdAt,
                        status: viewModel.statusText(item.status),
                        status: item.status
                    )
                }
            }
        }
        .padding(AppMetrics.Spacing.small)
        .background(.white, in: RoundedRectangle(cornerRadius: 12))
    }

    private var roleSection: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.xSmall) {
            sectionHeader("权限申请记录", count: viewModel.roleApplications.count, icon: "person.badge.shield.checkmark.fill")
            if viewModel.roleLoadFailed {
                sectionFailureRow("权限申请记录加载失败")
            } else if viewModel.roleApplications.isEmpty {
                Text("暂无权限申请记录")
                    .font(.system(size: AppMetrics.FontSize.caption))
                    .foregroundStyle(AppDesign.textSecondary)
            } else {
                ForEach(viewModel.roleApplications) { item in
                    reviewRow(
                        title: "\(item.roleName) · \(scenicNames(item.scenicList))",
                        code: item.code,
                        subtitle: item.createdAt,
                        status: viewModel.statusText(item.status, fallback: item.statusLabel),
                        status: item.status
                    )
                }
            }
        }
        .padding(AppMetrics.Spacing.small)
        .background(.white, in: RoundedRectangle(cornerRadius: 12))
    }

    private func sectionFailureRow(_ text: String) -> some View {
        HStack(spacing: AppMetrics.Spacing.xSmall) {
            Image(systemName: "exclamationmark.triangle")
                .foregroundStyle(AppDesign.warning)
            Text(text)
                .font(.system(size: AppMetrics.FontSize.caption))
                .foregroundStyle(AppDesign.textSecondary)
            Spacer(minLength: 0)
            Button("重试") {
                Task { await viewModel.load(api: scenicPermissionAPI) }
            }
            .font(.system(size: AppMetrics.FontSize.caption, weight: .semibold))
            .foregroundStyle(AppDesign.primary)
            .buttonStyle(.plain)
        }
        .padding(AppMetrics.Spacing.xSmall)
        .background(Color(hex: 0xFFF7ED), in: RoundedRectangle(cornerRadius: 8))
    }

    private func reviewRow(title: String, code: String, subtitle: String, status statusText: String, status: Int) -> some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.xSmall) {
            Text(title)
                .font(.system(size: AppMetrics.FontSize.subheadline, weight: .semibold))
                .foregroundStyle(AppDesign.textPrimary)
            Label("申请编号：\(code.settlementDash)", systemImage: "number.square.fill")
                .font(.system(size: AppMetrics.FontSize.caption, weight: .medium))
                .foregroundStyle(AppDesign.primary)
                .padding(.horizontal, AppMetrics.Spacing.small)
                .frame(height: 22)
                .background(AppDesign.primarySoft, in: Capsule())
            HStack {
                Label(statusText, systemImage: viewModel.statusIcon(status))
                    .font(.system(size: AppMetrics.FontSize.caption, weight: .medium))
                    .foregroundStyle(viewModel.statusColor(status))
                    .padding(.horizontal, AppMetrics.Spacing.small)
                    .frame(height: 22)
                    .background(viewModel.statusColor(status).opacity(0.12), in: Capsule())
                Spacer(minLength: 0)
                Label(subtitle.settlementDash, systemImage: "clock")
                    .font(.system(size: AppMetrics.FontSize.caption))
                    .foregroundStyle(AppDesign.textSecondary)
            }
        }
        .padding(AppMetrics.Spacing.xSmall)
        .background(Color(hex: 0xF8FAFC), in: RoundedRectangle(cornerRadius: 10))
    }

    private func summaryCard(_ title: String, _ value: String) -> some View {
        VStack(alignment: .leading, spacing: 4) {
            Text(title)
                .font(.system(size: AppMetrics.FontSize.caption))
                .foregroundStyle(AppDesign.textSecondary)
            Text(value)
                .font(.system(size: AppMetrics.FontSize.title, weight: .semibold))
                .foregroundStyle(AppDesign.textPrimary)
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(AppMetrics.Spacing.small)
        .background(.white, in: RoundedRectangle(cornerRadius: 12))
    }

    private func sectionHeader(_ title: String, count: Int, icon: String) -> some View {
        HStack(spacing: AppMetrics.Spacing.xSmall) {
            Image(systemName: icon)
                .font(.system(size: AppMetrics.FontSize.footnote, weight: .semibold))
                .foregroundStyle(AppDesign.primary)
            Text(title)
                .font(.system(size: AppMetrics.FontSize.subheadline, weight: .semibold))
                .foregroundStyle(AppDesign.textPrimary)
            Spacer()
            Text("\(count)")
                .font(.system(size: AppMetrics.FontSize.caption, weight: .medium))
                .foregroundStyle(AppDesign.primary)
                .padding(.horizontal, AppMetrics.Spacing.small)
                .frame(height: 22)
                .background(AppDesign.primarySoft, in: Capsule())
        }
    }

    private func scenicNames(_ items: [RoleApplyScenicItem]) -> String {
        let names = items.map(\.name).filter { !$0.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty }
        return names.isEmpty ? "--" : names.joined(separator: "、")
    }
}

private struct NewScenicBanner: View {
    let onApplyClick: () -> Void

    var body: some View {
        HStack(spacing: AppMetrics.Spacing.xSmall) {
            Image(systemName: "building.2.fill")
                .font(.system(size: 20, weight: .semibold))
                .foregroundStyle(Color(hex: 0xFF7B00))
            Text("没有找到心仪的景区")
                .font(.system(size: AppMetrics.FontSize.footnote, weight: .medium))
                .foregroundStyle(Color(hex: 0xFF7B00))
                .lineLimit(1)
                .minimumScaleFactor(0.85)
            Spacer()
            Button(action: onApplyClick) {
                HStack(spacing: 4) {
                    Text("申请平台开通新景区")
                        .lineLimit(1)
                        .minimumScaleFactor(0.8)
                    Image(systemName: "chevron.right")
                }
                .font(.system(size: AppMetrics.FontSize.caption, weight: .semibold))
                .foregroundStyle(Color(hex: 0xFF7B00))
            }
            .buttonStyle(.plain)
        }
        .padding(.horizontal, AppMetrics.Spacing.medium)
        .padding(.vertical, AppMetrics.Spacing.small)
        .background(Color(hex: 0xFFF0E2))
    }
}

private extension String {
    var settlementDash: String {
        let trimmed = trimmingCharacters(in: .whitespacesAndNewlines)
        return trimmed.isEmpty ? "--" : trimmed
    }
}
