//
//  PermissionApplyView.swift
//  suixinkan
//
//  Created by Codex on 2026/6/23.
//

import SwiftUI

/// 权限申请页面，支持申请某角色在更多景区下的权限。
struct PermissionApplyView: View {
    @Environment(PermissionContext.self) private var permissionContext
    @Environment(ScenicPermissionAPI.self) private var scenicPermissionAPI
    @State private var viewModel: PermissionApplyViewModel
    @State private var activePicker: PermissionPickerSheet?

    /// 初始化权限申请页面，可传入驳回记录用于编辑。
    init(initialPending: RoleApplyPendingResponse? = nil) {
        _viewModel = State(initialValue: PermissionApplyViewModel(initialPending: initialPending))
    }

    var body: some View {
        VStack(spacing: 0) {
            NavigationLink(value: AppRoute.home(.scenicApplication)) {
                NewScenicBanner()
            }
            .buttonStyle(.plain)

            ScrollView {
                VStack(alignment: .leading, spacing: AppMetrics.Spacing.large) {
                    roleSection
                    scenicSection
                    if !viewModel.existingRoleInfos.isEmpty {
                        existingRoleSection
                    }
                }
                .padding(AppMetrics.Spacing.medium)
                .background(.white, in: RoundedRectangle(cornerRadius: 8))
                .padding(AppMetrics.Spacing.medium)
            }

            submitBar
        }
        .background(Color(hex: 0xF4F4F4).ignoresSafeArea())
        .navigationTitle("申请权限")
        .navigationBarTitleDisplayMode(.inline)
        .task {
            viewModel.bootstrap(rolePermissions: permissionContext.rolePermissions)
            await viewModel.loadScenicListIfNeeded(api: scenicPermissionAPI)
        }
        .sheet(item: $activePicker) { picker in
            PermissionPickerSheetView(
                picker: picker,
                roleOptions: viewModel.roleOptions,
                selectedRoleId: viewModel.selectedRoleId,
                scenicOptions: viewModel.scenicOptions,
                selectedCount: viewModel.selectedCount,
                onSelectRole: { role in
                    if viewModel.selectedRoleId != role.id {
                        viewModel.selectRole(id: role.id)
                        Task { await viewModel.loadScenicListIfNeeded(api: scenicPermissionAPI, force: true) }
                    }
                    activePicker = nil
                },
                onToggleScenic: { scenic in
                    viewModel.toggleScenic(id: scenic.id)
                }
            )
            .presentationDetents([.medium, .large])
        }
        .alert("提示", isPresented: Binding(
            get: { viewModel.message != nil },
            set: { if !$0 { viewModel.message = nil } }
        )) {
            Button("知道了", role: .cancel) {}
        } message: {
            Text(viewModel.message ?? "")
        }
    }

    private var roleSection: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.xSmall) {
            HStack {
                Text("角色信息")
                    .font(.system(size: AppMetrics.FontSize.body, weight: .medium))
                Spacer()
                Text("单选")
                    .font(.system(size: AppMetrics.FontSize.caption))
                    .foregroundStyle(AppDesign.textSecondary)
            }
            Text("请选择您需要申请权限的角色")
                .font(.system(size: AppMetrics.FontSize.caption))
                .foregroundStyle(AppDesign.placeholder)
            pickerDisplay(
                title: viewModel.selectedRoleName ?? "请选择角色",
                subtitle: "点击选择申请角色",
                isPlaceholder: viewModel.selectedRoleId == nil,
                isDisabled: viewModel.roleOptions.isEmpty
            ) {
                guard !viewModel.roleOptions.isEmpty else { return }
                activePicker = .role
            }
            if let notes = viewModel.selectedRoleNotes, !notes.isEmpty {
                Text(notes)
                    .font(.system(size: AppMetrics.FontSize.caption))
                    .foregroundStyle(AppDesign.textSecondary)
                    .padding(AppMetrics.Spacing.small)
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .background(Color(hex: 0xF8FAFC), in: RoundedRectangle(cornerRadius: 10))
            }
        }
    }

    private var scenicSection: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.xSmall) {
            HStack {
                Text("选择景区")
                    .font(.system(size: AppMetrics.FontSize.body, weight: .medium))
                Spacer()
                Text("可多选")
                    .font(.system(size: AppMetrics.FontSize.caption))
                    .foregroundStyle(AppDesign.textSecondary)
            }
            Text("请选择您需要申请权限的景区")
                .font(.system(size: AppMetrics.FontSize.caption))
                .foregroundStyle(AppDesign.placeholder)
            pickerDisplay(
                title: viewModel.loadingScenics ? "加载景区中..." : viewModel.selectedScenicSummary,
                subtitle: viewModel.selectedRoleId == nil ? "请先选择角色" : "点击选择一个或多个景区",
                isPlaceholder: viewModel.selectedCount == 0,
                isDisabled: viewModel.selectedRoleId == nil || viewModel.loadingScenics || viewModel.scenicOptions.isEmpty
            ) {
                guard viewModel.selectedRoleId != nil else {
                    viewModel.message = "请先选择角色"
                    return
                }
                guard !viewModel.loadingScenics, !viewModel.scenicOptions.isEmpty else { return }
                activePicker = .scenic
            }
            if viewModel.scenicLoadFailed && viewModel.scenicOptions.isEmpty {
                HStack {
                    Image(systemName: "exclamationmark.triangle")
                        .foregroundStyle(AppDesign.warning)
                    Text("景区列表加载失败")
                        .font(.system(size: AppMetrics.FontSize.footnote))
                        .foregroundStyle(AppDesign.textSecondary)
                    Spacer()
                    Button("重新加载") {
                        Task { await viewModel.loadScenicListIfNeeded(api: scenicPermissionAPI, force: true) }
                    }
                    .font(.system(size: AppMetrics.FontSize.footnote, weight: .semibold))
                    .buttonStyle(.plain)
                }
                .padding(AppMetrics.Spacing.small)
                .background(Color(hex: 0xFFF7ED), in: RoundedRectangle(cornerRadius: 8))
            }
        }
    }

    private var existingRoleSection: some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.small) {
            Text("已有角色信息")
                .font(.system(size: AppMetrics.FontSize.body, weight: .medium))
            ForEach(viewModel.existingRoleInfos) { info in
                ExistingRolePermissionRow(info: info)
            }
        }
        .padding(AppMetrics.Spacing.small)
        .background(Color(hex: 0xF8F9FB), in: RoundedRectangle(cornerRadius: 12))
    }

    private var submitBar: some View {
        Button(viewModel.submitting ? "提交中..." : "提交审核") {
            Task { await viewModel.submit(api: scenicPermissionAPI) }
        }
        .disabled(!viewModel.canSubmit)
        .font(.system(size: AppMetrics.FontSize.body, weight: .medium))
        .foregroundStyle(.white)
        .frame(maxWidth: .infinity)
        .frame(height: AppMetrics.ControlSize.sheetButtonHeight)
        .background(viewModel.canSubmit ? AppDesign.primary : Color(hex: 0xD8D8D8), in: RoundedRectangle(cornerRadius: 8))
        .padding(AppMetrics.Spacing.medium)
        .background(.white)
    }

    /// 构建角色和景区选择框。
    private func pickerDisplay(
        title: String,
        subtitle: String,
        isPlaceholder: Bool,
        isDisabled: Bool,
        action: @escaping () -> Void
    ) -> some View {
        Button(action: action) {
            HStack(spacing: AppMetrics.Spacing.small) {
                VStack(alignment: .leading, spacing: AppMetrics.Spacing.xxSmall) {
                    Text(title)
                        .font(.system(size: AppMetrics.FontSize.subheadline, weight: isPlaceholder ? .regular : .semibold))
                        .foregroundStyle(isPlaceholder ? AppDesign.placeholder : AppDesign.textPrimary)
                        .lineLimit(1)
                    Text(subtitle)
                        .font(.system(size: 11))
                        .foregroundStyle(AppDesign.textSecondary)
                        .lineLimit(1)
                }
                Spacer()
                Image(systemName: "chevron.down")
                    .font(.system(size: AppMetrics.FontSize.subheadline, weight: .semibold))
                    .foregroundStyle(isDisabled ? Color(hex: 0xC7CDD6) : AppDesign.primary)
            }
            .padding(.horizontal, AppMetrics.Spacing.substantial)
            .frame(height: 58)
            .background(Color(hex: 0xFBFCFE), in: RoundedRectangle(cornerRadius: 10))
            .overlay {
                RoundedRectangle(cornerRadius: 10)
                    .stroke(isDisabled ? Color(hex: 0xE5E7EB) : AppDesign.primary.opacity(0.28), lineWidth: 1)
            }
        }
        .buttonStyle(.plain)
        .disabled(isDisabled)
    }
}

/// 新增景区申请入口横幅。
private struct NewScenicBanner: View {
    var body: some View {
        HStack(spacing: AppMetrics.Spacing.small) {
            Image(systemName: "plus.circle.fill")
                .font(.system(size: AppMetrics.FontSize.title3, weight: .semibold))
                .foregroundStyle(AppDesign.primary)
            VStack(alignment: .leading, spacing: AppMetrics.Spacing.xxSmall) {
                Text("没有找到想申请的景区？")
                    .font(.system(size: AppMetrics.FontSize.subheadline, weight: .semibold))
                    .foregroundStyle(AppDesign.textPrimary)
                Text("提交景区资料后等待平台审核")
                    .font(.system(size: AppMetrics.FontSize.caption))
                    .foregroundStyle(AppDesign.textSecondary)
            }
            Spacer()
            Image(systemName: "chevron.right")
                .font(.system(size: AppMetrics.FontSize.subheadline, weight: .semibold))
                .foregroundStyle(AppDesign.textSecondary)
        }
        .padding(.horizontal, AppMetrics.Spacing.medium)
        .frame(height: 64)
        .background(.white)
    }
}

/// 已有角色权限展示行。
private struct ExistingRolePermissionRow: View {
    let info: ExistingRolePermissionInfo
    @State private var expanded = true

    var body: some View {
        VStack(spacing: 0) {
            Button {
                withAnimation(.easeInOut(duration: 0.16)) {
                    expanded.toggle()
                }
            } label: {
                HStack {
                    Text(info.name)
                        .font(.system(size: AppMetrics.FontSize.subheadline, weight: .medium))
                        .foregroundStyle(AppDesign.textPrimary)
                        .lineLimit(1)
                    Spacer()
                    Image(systemName: expanded ? "chevron.up" : "chevron.down")
                        .foregroundStyle(AppDesign.textSecondary)
                }
                .padding(.horizontal, AppMetrics.Spacing.medium)
                .frame(height: 48)
            }
            .buttonStyle(.plain)

            if expanded && !info.scenics.isEmpty {
                LazyVGrid(columns: [GridItem(.adaptive(minimum: 90), spacing: AppMetrics.Spacing.xSmall)], alignment: .leading, spacing: AppMetrics.Spacing.xSmall) {
                    ForEach(info.scenics.prefix(6)) { scenic in
                        Text(scenic.name)
                            .font(.system(size: AppMetrics.FontSize.footnote))
                            .foregroundStyle(AppDesign.success)
                            .lineLimit(1)
                            .padding(.horizontal, AppMetrics.Spacing.small)
                            .frame(height: 34)
                            .background(Color(hex: 0xF0FAEE), in: RoundedRectangle(cornerRadius: 4))
                    }
                }
                .padding(AppMetrics.Spacing.small)
                .frame(maxWidth: .infinity, alignment: .leading)
                .background(Color(hex: 0xF8F9FB))
            }
        }
        .background(.white, in: RoundedRectangle(cornerRadius: 8))
    }
}

/// 权限申请选择器类型，区分角色单选和景区多选。
private enum PermissionPickerSheet: Identifiable {
    case role
    case scenic

    var id: String {
        switch self {
        case .role: "role"
        case .scenic: "scenic"
        }
    }

    var title: String {
        switch self {
        case .role: "选择角色"
        case .scenic: "选择景区"
        }
    }
}

/// 权限申请选择器弹层。
private struct PermissionPickerSheetView: View {
    @Environment(\.dismiss) private var dismiss
    let picker: PermissionPickerSheet
    let roleOptions: [PermissionRoleOption]
    let selectedRoleId: Int?
    let scenicOptions: [PermissionScenicOption]
    let selectedCount: Int
    let onSelectRole: (PermissionRoleOption) -> Void
    let onToggleScenic: (PermissionScenicOption) -> Void

    var body: some View {
        NavigationStack {
            ScrollView {
                LazyVStack(spacing: AppMetrics.Spacing.xSmall) {
                    switch picker {
                    case .role:
                        ForEach(roleOptions) { role in
                            roleRow(role)
                        }
                    case .scenic:
                        ForEach(scenicOptions) { scenic in
                            scenicRow(scenic)
                        }
                    }
                }
                .padding(AppMetrics.Spacing.medium)
            }
            .background(Color(hex: 0xF5F7FA).ignoresSafeArea())
            .navigationTitle(picker.title)
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("关闭") { dismiss() }
                }
                if picker == .scenic {
                    ToolbarItem(placement: .confirmationAction) {
                        Button("完成(\(selectedCount))") { dismiss() }
                    }
                }
            }
        }
    }

    /// 构建角色选择行。
    private func roleRow(_ role: PermissionRoleOption) -> some View {
        Button { onSelectRole(role) } label: {
            HStack(spacing: AppMetrics.Spacing.small) {
                VStack(alignment: .leading, spacing: AppMetrics.Spacing.xxSmall) {
                    Text(role.name)
                        .font(.system(size: AppMetrics.FontSize.subheadline, weight: .semibold))
                        .foregroundStyle(AppDesign.textPrimary)
                    if !role.notes.isEmpty {
                        Text(role.notes)
                            .font(.system(size: AppMetrics.FontSize.caption))
                            .foregroundStyle(AppDesign.textSecondary)
                            .lineLimit(2)
                    }
                }
                Spacer()
                Image(systemName: selectedRoleId == role.id ? "checkmark.circle.fill" : "circle")
                    .font(.system(size: AppMetrics.ControlSize.passwordIcon, weight: .semibold))
                    .foregroundStyle(selectedRoleId == role.id ? AppDesign.primary : Color(hex: 0xCBD5E1))
            }
            .padding(AppMetrics.Spacing.substantial)
            .background(.white, in: RoundedRectangle(cornerRadius: 12))
        }
        .buttonStyle(.plain)
    }

    /// 构建景区选择行。
    private func scenicRow(_ scenic: PermissionScenicOption) -> some View {
        Button { onToggleScenic(scenic) } label: {
            HStack(spacing: AppMetrics.Spacing.small) {
                Image(systemName: scenic.selected ? "checkmark.square.fill" : "square")
                    .font(.system(size: AppMetrics.ControlSize.passwordIcon, weight: .semibold))
                    .foregroundStyle(scenic.disabled ? Color(hex: 0xCBD5E1) : (scenic.selected ? AppDesign.primary : Color(hex: 0xCBD5E1)))
                VStack(alignment: .leading, spacing: AppMetrics.Spacing.xxSmall) {
                    Text(scenic.name)
                        .font(.system(size: AppMetrics.FontSize.subheadline, weight: .medium))
                        .foregroundStyle(scenic.disabled ? AppDesign.textSecondary : AppDesign.textPrimary)
                        .lineLimit(1)
                    if scenic.disabled {
                        Text("已有该角色权限")
                            .font(.system(size: 11))
                            .foregroundStyle(AppDesign.textSecondary)
                    }
                }
                Spacer()
            }
            .padding(AppMetrics.Spacing.substantial)
            .background(.white, in: RoundedRectangle(cornerRadius: 12))
            .opacity(scenic.disabled ? 0.62 : 1)
        }
        .buttonStyle(.plain)
        .disabled(scenic.disabled)
    }
}
