//
//  AccountSwitchViewController.swift
//  suixinkan
//

import SnapKit
import UIKit

private typealias AccountSwitchSection = Int
private typealias AccountSwitchItem = String

/// 账号切换页面，展示当前登录主体下可进入的景区账号和门店账号。
final class AccountSwitchViewController: BaseViewController, UITableViewDelegate {

    private let viewModel = AccountSwitchViewModel()
    private let profileAPI = NetworkServices.shared.profileAPI
    private let authAPI = NetworkServices.shared.authAPI

    private lazy var tableView: UITableView = {
        let table = UITableView(frame: .zero, style: .plain)
        table.backgroundColor = UIColor(hex: 0xF5F7FB)
        table.separatorStyle = .none
        table.delegate = self
        table.register(AccountSwitchCell.self, forCellReuseIdentifier: AccountSwitchCell.reuseID)
        return table
    }()

    private let confirmButton = AppButton(title: "确认切换")

    private var tableDataSource: UITableViewDiffableDataSource<AccountSwitchSection, AccountSwitchItem>!

    override func setupNavigationBar() {
        title = "账号切换"
    }

    override func setupUI() {
        view.backgroundColor = UIColor(hex: 0xF5F7FB)
        configureTableDataSource()
        view.addSubview(tableView)
        view.addSubview(confirmButton)
    }

    override func setupConstraints() {
        tableView.snp.makeConstraints { make in
            make.top.leading.trailing.equalToSuperview()
            make.bottom.equalTo(confirmButton.snp.top).offset(-12)
        }
        confirmButton.snp.makeConstraints { make in
            make.leading.trailing.equalToSuperview().inset(16)
            make.bottom.equalTo(view.safeAreaLayoutGuide).inset(14)
        }
    }

    override func bindActions() {
        viewModel.onStateChange = { [weak self] in
            self?.applyTableSnapshot(reconfigure: true)
            self?.updateConfirmButton()
        }
        confirmButton.addTarget(self, action: #selector(confirmTapped), for: .touchUpInside)
        Task { await loadAccounts() }
    }

    private func configureTableDataSource() {
        tableDataSource = UITableViewDiffableDataSource(tableView: tableView) { [weak self] tableView, indexPath, item in
            guard let self else { return UITableViewCell() }
            let cell = tableView.dequeueReusableCell(withIdentifier: AccountSwitchCell.reuseID, for: indexPath) as! AccountSwitchCell
            guard let account = self.viewModel.accounts.first(where: { $0.id == item }) else { return cell }
            cell.configure(
                account: account,
                selected: account.id == self.viewModel.selectedAccountId,
                isCurrent: account.isCurrent || self.isCurrentAccount(account)
            )
            return cell
        }
        applyTableSnapshot(animated: false)
    }

    private func buildSnapshot() -> NSDiffableDataSourceSnapshot<AccountSwitchSection, AccountSwitchItem> {
        var snapshot = NSDiffableDataSourceSnapshot<AccountSwitchSection, AccountSwitchItem>()
        snapshot.appendSections([0])
        snapshot.appendItems(viewModel.accounts.map(\.id), toSection: 0)
        return snapshot
    }

    private func applyTableSnapshot(animated: Bool = true, reconfigure: Bool = false) {
        var snapshot = buildSnapshot()
        if reconfigure, !snapshot.itemIdentifiers.isEmpty {
            snapshot.reconfigureItems(snapshot.itemIdentifiers)
        }
        tableDataSource.apply(snapshot, animatingDifferences: animated)
    }

    private func updateConfirmButton() {
        let enabled = viewModel.selectedAccount != nil && !viewModel.loading && !viewModel.switching
        confirmButton.isEnabled = enabled
    }

    private var currentAccountId: String? {
        let store = AppStore.shared
        if store.session.currentStoreId > 0 {
            return "\(V9StoreUser.accountTypeValue)_\(store.session.currentStoreId)"
        }
        if store.session.currentScenicId > 0 {
            return "\(V9ScenicUser.accountTypeValue)_\(store.session.userId)"
        }
        return store.session.userId.isEmpty ? nil : store.session.userId
    }

    private func isCurrentAccount(_ account: AccountSwitchAccount) -> Bool {
        viewModel.isCurrent(account, currentAccountId: currentAccountId)
    }

    private func loadAccounts(force: Bool = false) async {
        showLoading()
        defer { hideLoading() }
        do {
            try await viewModel.load(api: profileAPI, force: force, currentAccountId: currentAccountId)
        } catch {
            showToast(error.localizedDescription)
        }
    }

    @objc private func confirmTapped() {
        guard let account = viewModel.selectedAccount else { return }
        if account.isCurrent || isCurrentAccount(account) {
            navigationController?.popViewController(animated: true)
            return
        }
        Task { await switchAccount(account) }
    }

    private func switchAccount(_ account: AccountSwitchAccount) async {
        showLoading()
        defer { hideLoading() }
        do {
            let response = try await viewModel.switchAccount(account, api: authAPI)
            AuthSessionHelper.applyAccountSwitch(with: response, account: account)
            showToast("账号已切换")
            navigationController?.popViewController(animated: true)
        } catch {
            showToast(error.localizedDescription)
        }
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        guard let item = tableDataSource.itemIdentifier(for: indexPath),
              let account = viewModel.accounts.first(where: { $0.id == item }) else { return }
        viewModel.select(account)
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 92 }
}

private final class AccountSwitchCell: UITableViewCell {
    static let reuseID = "AccountSwitchCell"

    private let card = UIView()
    private let avatarView = UIImageView()
    private let titleStackView = UIStackView()
    private let titleLabel = UILabel()
    private let currentTagLabel = UILabel()
    private let subtitleLabel = UILabel()
    private let nameLabel = UILabel()
    private let tagLabel = UILabel()
    private let checkView = UIImageView()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        selectionStyle = .none
        backgroundColor = .clear

        card.backgroundColor = .white
        card.layer.cornerRadius = 12
        contentView.addSubview(card)

        avatarView.layer.cornerRadius = 25
        avatarView.clipsToBounds = true
        avatarView.contentMode = .scaleAspectFill

        titleStackView.axis = .horizontal
        titleStackView.alignment = .center
        titleStackView.spacing = 6

        titleLabel.font = .systemFont(ofSize: 16, weight: .semibold)
        titleLabel.numberOfLines = 1
        titleLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
        currentTagLabel.font = .systemFont(ofSize: 11, weight: .regular)
        currentTagLabel.text = "当前"
        currentTagLabel.textColor = AppColor.primary
        currentTagLabel.textAlignment = .center
        currentTagLabel.backgroundColor = UIColor(hex: 0xEFF6FF)
        currentTagLabel.layer.cornerRadius = 4
        currentTagLabel.clipsToBounds = true
        currentTagLabel.isHidden = true
        currentTagLabel.setContentHuggingPriority(.required, for: .horizontal)
        currentTagLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
        subtitleLabel.font = .systemFont(ofSize: 13)
        subtitleLabel.textColor = AppColor.text666
        nameLabel.font = .systemFont(ofSize: 12)
        nameLabel.textColor = UIColor(hex: 0x9AA1AA)
        tagLabel.font = .systemFont(ofSize: 11, weight: .semibold)
        tagLabel.textAlignment = .center
        tagLabel.layer.cornerRadius = 4
        tagLabel.clipsToBounds = true

        card.addSubview(avatarView)
        titleStackView.addArrangedSubview(titleLabel)
        titleStackView.addArrangedSubview(currentTagLabel)

        card.addSubview(titleStackView)
        card.addSubview(subtitleLabel)
        card.addSubview(nameLabel)
        card.addSubview(tagLabel)
        card.addSubview(checkView)

        card.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(UIEdgeInsets(top: 6, left: 16, bottom: 6, right: 16))
        }
        avatarView.snp.makeConstraints { make in
            make.leading.centerY.equalToSuperview().inset(14)
            make.width.height.equalTo(50)
        }
        titleStackView.snp.makeConstraints { make in
            make.leading.equalTo(avatarView.snp.trailing).offset(13)
            make.top.equalTo(avatarView).offset(2)
            make.trailing.lessThanOrEqualTo(tagLabel.snp.leading).offset(-8)
        }
        currentTagLabel.snp.makeConstraints { make in
            make.height.equalTo(19)
            make.width.greaterThanOrEqualTo(34)
        }
        subtitleLabel.snp.makeConstraints { make in
            make.leading.equalTo(titleStackView)
            make.top.equalTo(titleStackView.snp.bottom).offset(4)
        }
        nameLabel.snp.makeConstraints { make in
            make.leading.equalTo(titleLabel)
            make.top.equalTo(subtitleLabel.snp.bottom).offset(4)
        }
        tagLabel.snp.makeConstraints { make in
            make.trailing.equalToSuperview().inset(14)
            make.top.equalToSuperview().offset(14)
            make.height.equalTo(22)
            make.width.greaterThanOrEqualTo(40)
        }
        checkView.snp.makeConstraints { make in
            make.trailing.bottom.equalToSuperview().inset(14)
            make.width.height.equalTo(22)
        }
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) { fatalError() }

    func configure(account: AccountSwitchAccount, selected: Bool, isCurrent: Bool) {
        titleLabel.text = account.title
        currentTagLabel.isHidden = !isCurrent
        subtitleLabel.text = account.subtitle
        subtitleLabel.isHidden = account.subtitle.isEmpty
        nameLabel.text = account.realName
        nameLabel.isHidden = account.realName.isEmpty
        tagLabel.text = account.isStoreUser ? "门店" : "景区"
        tagLabel.textColor = account.isStoreUser ? UIColor(hex: 0x0F9F6E) : UIColor(hex: 0x7C3AED)
        tagLabel.backgroundColor = account.isStoreUser ? UIColor(hex: 0xE8F8F1) : UIColor(hex: 0xF3ECFF)
        checkView.image = UIImage(systemName: selected ? "checkmark.circle.fill" : "circle")
        checkView.tintColor = selected ? AppColor.primary : UIColor(hex: 0xB6BECA)
        avatarView.loadRemoteImage(urlString: account.avatar)
    }
}
