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

import SwiftUI

/// 账号切换页面，展示当前登录主体下可进入的景区账号和门店账号。
struct AccountSwitchView: View {
    @Environment(AppSession.self) private var appSession
    @Environment(AccountContext.self) private var accountContext
    @Environment(PermissionContext.self) private var permissionContext
    @Environment(AppRouter.self) private var appRouter
    @Environment(ProfileAPI.self) private var profileAPI
    @Environment(AuthAPI.self) private var authAPI
    @Environment(AccountContextAPI.self) private var accountContextAPI
    @Environment(AuthSessionCoordinator.self) private var authSessionCoordinator
    @Environment(ToastCenter.self) private var toastCenter
    @Environment(\.globalLoading) private var globalLoading
    @Environment(\.dismiss) private var dismiss

    @State private var viewModel = AccountSwitchViewModel()

    private var selectedAccount: AccountSwitchAccount? {
        viewModel.selectedAccount
    }

    var body: some View {
        VStack(spacing: 0) {
            accountList
            bottomBar
        }
        .background(Color(hex: 0xF5F7FB).ignoresSafeArea())
        .navigationTitle("账号切换")
        .navigationBarTitleDisplayMode(.inline)
        .task {
            await loadAccounts()
        }
    }

    @ViewBuilder
    private var accountList: some View {
        if viewModel.accounts.isEmpty && !viewModel.loading {
            ContentUnavailableView(
                "暂无可切换账号",
                systemImage: "person.crop.circle.badge.exclamationmark",
                description: Text("当前登录账号下没有其他可切换账号。")
            )
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .padding(24)
        } else {
            ScrollView {
                LazyVStack(spacing: 12) {
                    ForEach(viewModel.accounts) { account in
                        accountCard(account)
                    }
                }
                .padding(16)
                .padding(.bottom, 92)
            }
            .refreshable {
                await loadAccounts(force: true)
            }
        }
    }

    private var bottomBar: some View {
        VStack(spacing: 0) {
            Divider()
            Button {
                Task { await confirmSelection() }
            } label: {
                Text("确认切换")
                    .font(.system(size: 16, weight: .semibold))
                    .foregroundStyle(.white)
                .frame(maxWidth: .infinity)
                .frame(height: 50)
                .background(canConfirm ? AppDesign.primary : Color(hex: 0xC9CED6), in: RoundedRectangle(cornerRadius: 12))
                .padding(.horizontal, 16)
                .padding(.vertical, 14)
            }
            .buttonStyle(.plain)
            .disabled(!canConfirm)
        }
        .background(.white)
    }

    private var canConfirm: Bool {
        selectedAccount != nil && !viewModel.loading && !viewModel.switching
    }

    /// 构造单个账号卡片。
    private func accountCard(_ account: AccountSwitchAccount) -> some View {
        let selected = viewModel.selectedAccountId == account.id
        return Button {
            viewModel.select(account)
        } label: {
            HStack(spacing: 13) {
                accountAvatar(account)

                VStack(alignment: .leading, spacing: 5) {
                    HStack(spacing: 8) {
                        Text(nonEmpty(account.title) ?? account.accountTypeLabel)
                            .font(.system(size: 16, weight: .semibold))
                            .foregroundStyle(AppDesign.textPrimary)
                            .lineLimit(1)
                        if account.isCurrent || isCurrentAccount(account) {
                            tag("当前", foreground: AppDesign.primary, background: AppDesign.primarySoft)
                        }
                    }

                    if !account.subtitle.isEmpty {
                        Text(account.subtitle)
                            .font(.system(size: 13))
                            .foregroundStyle(AppDesign.textSecondary)
                            .lineLimit(1)
                    }

                    if !account.phone.isEmpty {
                        Text(account.phone)
                            .font(.system(size: 12))
                            .foregroundStyle(Color(hex: 0x9AA1AA))
                    }
                }
                .frame(maxWidth: .infinity, alignment: .leading)

                VStack(alignment: .trailing, spacing: 8) {
                    tag(
                        account.isStoreUser ? "门店" : "景区",
                        foreground: account.isStoreUser ? Color(hex: 0x0F9F6E) : Color(hex: 0x7C3AED),
                        background: account.isStoreUser ? Color(hex: 0xE8F8F1) : Color(hex: 0xF3ECFF)
                    )
                    Image(systemName: selected ? "checkmark.circle.fill" : "circle")
                        .font(.system(size: 22, weight: .semibold))
                        .foregroundStyle(selected ? AppDesign.primary : Color(hex: 0xB6BECA))
                }
            }
            .padding(14)
            .background(.white, in: RoundedRectangle(cornerRadius: 12))
            .overlay {
                RoundedRectangle(cornerRadius: 12)
                    .stroke(selected ? AppDesign.primary : Color(hex: 0xE6ECF4), lineWidth: selected ? 1.4 : 1)
            }
            .shadow(color: Color(hex: 0xC8D7EA, alpha: selected ? 0.24 : 0.12), radius: selected ? 10 : 6, x: 0, y: 5)
        }
        .buttonStyle(.plain)
    }

    @ViewBuilder
    /// 构造账号头像，网络图加载失败时显示账号类型首字。
    private func accountAvatar(_ account: AccountSwitchAccount) -> some View {
        RemoteImage(urlString: account.avatar) {
            avatarFallback(account)
        }
        .frame(width: 50, height: 50)
        .clipShape(Circle())
    }

    /// 构造账号头像占位。
    private func avatarFallback(_ account: AccountSwitchAccount) -> some View {
        ZStack {
            Circle()
                .fill(account.isStoreUser ? Color(hex: 0xE8F8F1) : Color(hex: 0xF3ECFF))
            Text(account.isStoreUser ? "店" : "景")
                .font(.system(size: 17, weight: .semibold))
                .foregroundStyle(account.isStoreUser ? Color(hex: 0x0F9F6E) : Color(hex: 0x7C3AED))
        }
    }

    /// 构造账号标签。
    private func tag(_ text: String, foreground: Color, background: Color) -> some View {
        Text(text)
            .font(.system(size: 11, weight: .semibold))
            .foregroundStyle(foreground)
            .padding(.horizontal, 7)
            .frame(height: 22)
            .background(background, in: RoundedRectangle(cornerRadius: 4))
    }

    /// 拉取账号列表。
    private func loadAccounts(force: Bool = false) async {
        do {
            try await globalLoading.withOptionalLoading(!force && viewModel.accounts.isEmpty, message: "加载中...") {
                try await viewModel.load(api: profileAPI, force: force, currentAccountId: currentAccountId)
            }
        } catch is CancellationError {
            return
        } catch {
            toastCenter.show(error.localizedDescription)
        }
    }

    /// 确认账号切换，并刷新全局登录上下文。
    private func confirmSelection() async {
        guard let account = selectedAccount else { return }
        if isCurrentAccount(account) {
            dismiss()
            return
        }

        do {
            try await globalLoading.withLoading(message: "账号切换中...") {
                let response = try await viewModel.switchAccount(account, api: authAPI)
                let username = nonEmpty(accountContext.profile?.phone) ?? nonEmpty(account.phone) ?? ""
                try await authSessionCoordinator.completeLogin(
                    with: response,
                    username: username,
                    privacyAgreementAccepted: authSessionCoordinator.loginPreferences().privacyAgreementAccepted,
                    appSession: appSession,
                    accountContext: accountContext,
                    permissionContext: permissionContext,
                    profileAPI: profileAPI,
                    accountContextAPI: accountContextAPI
                )
            }
            appRouter.reset()
            toastCenter.show("账号已切换")
            dismiss()
        } catch is CancellationError {
            return
        } catch {
            toastCenter.show(error.localizedDescription)
        }
    }

    private var currentAccountId: String? {
        guard let current = accountContext.profile else { return nil }
        if let store = accountContext.currentStore {
            return "\(V9StoreUser.accountTypeValue)_\(store.id)"
        }
        if let scenic = accountContext.currentScenic {
            return "\(V9ScenicUser.accountTypeValue)_\(scenic.id)"
        }
        return current.userId.isEmpty ? nil : current.userId
    }

    /// 判断账号是否为当前已选账号。
    private func isCurrentAccount(_ account: AccountSwitchAccount) -> Bool {
        account.isCurrent || viewModel.isCurrent(account, currentAccountId: currentAccountId)
    }

    /// 返回去空白后的非空文本。
    private func nonEmpty(_ value: String?) -> String? {
        let text = value?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
        return text.isEmpty ? nil : text
    }
}
