//
//  TravelAlbumEntryViewController.swift
//  suixinkan
//

import Kingfisher
import SnapKit
import UIKit

/// 新增相册入口页，对齐 Android `TravelAlbumEntryScreen`。
final class TravelAlbumEntryViewController: BaseViewController {
    private let viewModel = TravelAlbumEntryViewModel()
    private let api: any TravelAlbumServing

    private let heroCard = TravelAlbumHeroCard()
    private let titleLabel = UILabel()
    private let tableView = UITableView(frame: .zero, style: .plain)
    private let emptyView = TravelAlbumEmptyView()
    private var dataSource: UITableViewDiffableDataSource<Int, TravelAlbum>!

    init(api: (any TravelAlbumServing)? = nil) {
        self.api = api ?? NetworkServices.shared.travelAlbumAPI
        super.init(nibName: nil, bundle: nil)
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func setupNavigationBar() {
        title = "新增相册"
        navigationController?.setNavigationBarHidden(false, animated: false)
    }

    override func setupUI() {
        view.backgroundColor = .white

        titleLabel.font = .systemFont(ofSize: 18, weight: .bold)
        titleLabel.textColor = .black

        tableView.backgroundColor = .white
        tableView.separatorStyle = .none
        tableView.rowHeight = UITableView.automaticDimension
        tableView.estimatedRowHeight = 148
        tableView.delegate = self
        tableView.register(TravelAlbumTaskCell.self, forCellReuseIdentifier: TravelAlbumTaskCell.reuseIdentifier)

        dataSource = UITableViewDiffableDataSource<Int, TravelAlbum>(tableView: tableView) {
            [weak self] tableView, indexPath, album in
            let cell = tableView.dequeueReusableCell(
                withIdentifier: TravelAlbumTaskCell.reuseIdentifier,
                for: indexPath
            ) as! TravelAlbumTaskCell
            cell.apply(album: album)
            cell.onShootUpload = { [weak self] in self?.pushWiredTransfer(album: album) }
            cell.onAlbumCode = { [weak self] in self?.loadAlbumCode(album) }
            return cell
        }

        view.addSubview(heroCard)
        view.addSubview(titleLabel)
        view.addSubview(tableView)
        view.addSubview(emptyView)
    }

    override func setupConstraints() {
        heroCard.snp.makeConstraints { make in
            make.top.equalTo(view.safeAreaLayoutGuide).offset(20)
            make.leading.trailing.equalToSuperview().inset(20)
            make.height.equalTo(108)
        }
        titleLabel.snp.makeConstraints { make in
            make.top.equalTo(heroCard.snp.bottom).offset(28)
            make.leading.trailing.equalToSuperview().inset(20)
        }
        tableView.snp.makeConstraints { make in
            make.top.equalTo(titleLabel.snp.bottom).offset(8)
            make.leading.trailing.bottom.equalToSuperview()
        }
        emptyView.snp.makeConstraints { make in
            make.top.equalTo(heroCard.snp.bottom)
            make.leading.trailing.bottom.equalToSuperview()
        }
    }

    override func bindActions() {
        heroCard.addTarget(self, action: #selector(createTapped), for: .touchUpInside)
        viewModel.onStateChange = { [weak self] in
            Task { @MainActor in self?.applyViewModel() }
        }
        viewModel.onShowMessage = { [weak self] message in
            Task { @MainActor in self?.showToast(message) }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        Task { await viewModel.loadAlbums(api: api) }
    }

    @MainActor
    private func applyViewModel() {
        heroCard.isLoading = viewModel.isCreating
        titleLabel.text = "我的任务（\(viewModel.albumTotal)）"
        titleLabel.isHidden = viewModel.albums.isEmpty
        tableView.isHidden = viewModel.albums.isEmpty
        emptyView.isHidden = !viewModel.albums.isEmpty || viewModel.isLoading
        var snapshot = NSDiffableDataSourceSnapshot<Int, TravelAlbum>()
        snapshot.appendSections([0])
        snapshot.appendItems(viewModel.albums)
        dataSource.apply(snapshot, animatingDifferences: true)
        if viewModel.isLoading && viewModel.albums.isEmpty {
            showLoading()
        } else {
            hideLoading()
        }
    }

    @objc private func createTapped() {
        Task {
            await viewModel.openCreateSheet(api: api)
            await MainActor.run {
                guard viewModel.isCreateSheetVisible, presentedViewController == nil else { return }
                let sheet = CreateTravelAlbumSheetViewController(viewModel: viewModel, api: api)
                sheet.onDismissed = { [weak self] in self?.viewModel.dismissCreateSheet() }
                present(sheet, animated: true)
            }
        }
    }

    private func loadAlbumCode(_ album: TravelAlbum) {
        Task {
            await viewModel.openAlbumCode(album: album, api: api)
            await MainActor.run { self.presentAlbumCodeIfNeeded() }
        }
    }

    @MainActor
    private func presentAlbumCodeIfNeeded() {
        guard let state = viewModel.albumCodeState else { return }
        let controller = TravelAlbumCodeDialogViewController(state: state)
        controller.onClose = { [weak self] in self?.viewModel.dismissAlbumCode() }
        controller.onDownload = { [weak self, weak controller] in
            guard let self, let url = self.viewModel.albumCodeState?.qrImageUrl, !url.isEmpty else { return }
            self.viewModel.setDownloadingQRCode(true)
            controller?.updateDownloading(true)
            Task {
                do {
                    try await ScenicQueueQRCodeSaver.saveImage(from: url)
                    await MainActor.run { self.showToast("已保存到相册") }
                } catch {
                    await MainActor.run { self.showToast(error.localizedDescription) }
                }
                await MainActor.run {
                    self.viewModel.setDownloadingQRCode(false)
                    controller?.updateDownloading(false)
                }
            }
        }
        present(controller, animated: true)
    }

    private func pushWiredTransfer(album: TravelAlbum) {
        let controller = WiredCameraTransferViewController(
            viewModel: WiredCameraTransferViewModel(
                albumId: album.id,
                albumTitle: album.name,
                headerPhone: album.displayPhone
            )
        )
        navigationController?.pushViewController(controller, animated: true)
    }
}

extension TravelAlbumEntryViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        guard let album = dataSource.itemIdentifier(for: indexPath) else { return }
        navigationController?.pushViewController(TravelAlbumDetailViewController(albumId: album.id), animated: true)
    }
}

/// 新建相册任务蓝色入口卡片。
private final class TravelAlbumHeroCard: UIControl {
    private let gradientLayer = CAGradientLayer()
    private let plusView = UIView()
    private let plusImageView = UIImageView(image: UIImage(systemName: "plus"))
    private let titleLabel = UILabel()
    private let subtitleLabel = UILabel()
    private let arrowLabel = UILabel()

    var isLoading = false {
        didSet { titleLabel.text = isLoading ? "新建中..." : "新建相册任务" }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        layer.cornerRadius = 10
        clipsToBounds = true
        gradientLayer.colors = [UIColor(hex: 0x007BFF).cgColor, UIColor(hex: 0x3A91FF).cgColor]
        gradientLayer.startPoint = CGPoint(x: 0, y: 0.5)
        gradientLayer.endPoint = CGPoint(x: 1, y: 0.5)
        layer.insertSublayer(gradientLayer, at: 0)

        plusView.backgroundColor = .white
        plusView.layer.cornerRadius = 17
        plusView.clipsToBounds = true
        plusImageView.tintColor = AppColor.primary
        plusImageView.contentMode = .scaleAspectFit

        titleLabel.text = "新建相册任务"
        titleLabel.font = .systemFont(ofSize: 19, weight: .medium)
        titleLabel.textColor = .white
        subtitleLabel.text = "创建一个新的相册拍摄任务"
        subtitleLabel.font = .systemFont(ofSize: 14)
        subtitleLabel.textColor = .white
        arrowLabel.text = "›"
        arrowLabel.textColor = .white
        arrowLabel.font = .systemFont(ofSize: 36, weight: .light)

        addSubview(plusView)
        plusView.addSubview(plusImageView)
        addSubview(titleLabel)
        addSubview(subtitleLabel)
        addSubview(arrowLabel)
        plusView.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(28)
            make.centerY.equalToSuperview()
            make.size.equalTo(34)
        }
        plusImageView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.size.equalTo(26)
        }
        titleLabel.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(30)
            make.leading.equalTo(plusView.snp.trailing).offset(16)
            make.trailing.lessThanOrEqualTo(arrowLabel.snp.leading).offset(-8)
        }
        subtitleLabel.snp.makeConstraints { make in
            make.top.equalTo(titleLabel.snp.bottom).offset(8)
            make.leading.equalTo(titleLabel)
            make.trailing.lessThanOrEqualTo(arrowLabel.snp.leading).offset(-8)
        }
        arrowLabel.snp.makeConstraints { make in
            make.trailing.equalToSuperview().offset(-18)
            make.centerY.equalToSuperview()
        }
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        gradientLayer.frame = bounds
    }
}

/// 旅拍相册任务列表 cell。
private final class TravelAlbumTaskCell: UITableViewCell {
    static let reuseIdentifier = "TravelAlbumTaskCell"

    var onShootUpload: (() -> Void)?
    var onAlbumCode: (() -> Void)?

    private let cardView = UIView()
    private let coverView = UIImageView()
    private let iconView = UIImageView(image: UIImage(systemName: "checklist"))
    private let nameLabel = UILabel()
    private let timeLabel = UILabel()
    private let phoneLabel = UILabel()
    private let codeButton = UIButton(type: .system)
    private let uploadButton = UIButton(type: .system)

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        selectionStyle = .none
        backgroundColor = .clear
        contentView.backgroundColor = .white
        cardView.backgroundColor = .white
        cardView.layer.cornerRadius = 10
        cardView.layer.shadowColor = UIColor(hex: 0x2F6BFF).withAlphaComponent(0.10).cgColor
        cardView.layer.shadowOpacity = 1
        cardView.layer.shadowRadius = 10
        cardView.layer.shadowOffset = CGSize(width: 0, height: 4)

        coverView.backgroundColor = UIColor(hex: 0xEAF2FF)
        coverView.layer.cornerRadius = 8
        coverView.clipsToBounds = true
        coverView.contentMode = .scaleAspectFill
        iconView.tintColor = AppColor.primary
        iconView.contentMode = .scaleAspectFit

        nameLabel.font = .systemFont(ofSize: 16, weight: .bold)
        nameLabel.textColor = AppColor.textPrimary
        nameLabel.numberOfLines = 1
        timeLabel.font = .systemFont(ofSize: 12)
        timeLabel.textColor = AppColor.textTertiary
        timeLabel.numberOfLines = 1
        phoneLabel.font = .systemFont(ofSize: 12)
        phoneLabel.textColor = AppColor.textTertiary
        phoneLabel.numberOfLines = 1
        phoneLabel.setContentCompressionResistancePriority(.required, for: .vertical)

        codeButton.setImage(UIImage(systemName: "qrcode"), for: .normal)
        codeButton.tintColor = .black
        uploadButton.setImage(UIImage(systemName: "camera.fill"), for: .normal)
        uploadButton.setTitle(" 拍摄上传", for: .normal)
        uploadButton.tintColor = AppColor.primary
        uploadButton.setTitleColor(AppColor.primary, for: .normal)
        uploadButton.titleLabel?.font = .systemFont(ofSize: 13, weight: .bold)
        uploadButton.backgroundColor = UIColor(hex: 0xEAF4FF)
        uploadButton.layer.cornerRadius = 8

        contentView.addSubview(cardView)
        cardView.addSubview(coverView)
        coverView.addSubview(iconView)
        cardView.addSubview(nameLabel)
        cardView.addSubview(timeLabel)
        cardView.addSubview(phoneLabel)
        cardView.addSubview(codeButton)
        cardView.addSubview(uploadButton)

        cardView.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(UIEdgeInsets(top: 6, left: 20, bottom: 6, right: 20))
        }
        coverView.snp.makeConstraints { make in
            make.leading.top.bottom.equalToSuperview().inset(12)
            make.size.equalTo(112)
        }
        iconView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.size.equalTo(42)
        }
        codeButton.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(12)
            make.trailing.equalToSuperview().offset(-10)
            make.size.equalTo(26)
        }
        nameLabel.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(14)
            make.leading.equalTo(coverView.snp.trailing).offset(12)
            make.trailing.equalTo(codeButton.snp.leading).offset(-8)
        }
        timeLabel.snp.makeConstraints { make in
            make.top.equalTo(nameLabel.snp.bottom).offset(7)
            make.leading.equalTo(nameLabel)
            make.trailing.equalToSuperview().offset(-12)
        }
        phoneLabel.snp.makeConstraints { make in
            make.top.equalTo(timeLabel.snp.bottom).offset(5)
            make.leading.equalTo(nameLabel)
            make.trailing.equalToSuperview().offset(-12)
        }
        uploadButton.snp.makeConstraints { make in
            make.top.equalTo(phoneLabel.snp.bottom).offset(9)
            make.trailing.equalToSuperview().offset(-10)
            make.bottom.equalToSuperview().offset(-12)
            make.height.equalTo(34)
            make.width.greaterThanOrEqualTo(104)
        }

        uploadButton.addTarget(self, action: #selector(uploadTapped), for: .touchUpInside)
        codeButton.addTarget(self, action: #selector(codeTapped), for: .touchUpInside)
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func apply(album: TravelAlbum) {
        nameLabel.text = album.name.isEmpty ? "未命名任务" : album.name
        timeLabel.text = "创建时间：\(TravelAlbumDisplayFormatter.shortTaskTime(album.createdAt))"
        phoneLabel.text = "手机号：\(album.displayPhone.isEmpty ? "--" : album.displayPhone)"
        if let url = URL(string: album.coverUrl), !album.coverUrl.isEmpty {
            iconView.isHidden = true
            coverView.kf.setImage(with: url)
        } else {
            coverView.image = nil
            iconView.isHidden = false
        }
    }

    @objc private func uploadTapped() { onShootUpload?() }
    @objc private func codeTapped() { onAlbumCode?() }
}

/// 旅拍相册空态视图。
private final class TravelAlbumEmptyView: UIView {
    private let imageView = UIImageView(image: UIImage(systemName: "photo.on.rectangle.angled"))
    private let titleLabel = UILabel()
    private let subtitleLabel = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)
        isHidden = true
        imageView.tintColor = AppColor.primary
        imageView.contentMode = .scaleAspectFit
        titleLabel.text = "暂无任务"
        titleLabel.font = .systemFont(ofSize: 18, weight: .bold)
        titleLabel.textColor = .black
        titleLabel.textAlignment = .center
        subtitleLabel.text = "点击“新建相册任务”开始创建任务"
        subtitleLabel.font = .systemFont(ofSize: 14)
        subtitleLabel.textColor = AppColor.textTertiary
        subtitleLabel.textAlignment = .center

        let backdrop = UIView()
        backdrop.backgroundColor = UIColor(hex: 0xF2F7FF)
        backdrop.layer.cornerRadius = 54
        addSubview(backdrop)
        addSubview(imageView)
        addSubview(titleLabel)
        addSubview(subtitleLabel)
        backdrop.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.centerY.equalToSuperview().offset(-70)
            make.width.equalToSuperview().multipliedBy(0.58)
            make.height.equalTo(108)
        }
        imageView.snp.makeConstraints { make in
            make.center.equalTo(backdrop)
            make.size.equalTo(82)
        }
        titleLabel.snp.makeConstraints { make in
            make.top.equalTo(backdrop.snp.bottom).offset(22)
            make.leading.trailing.equalToSuperview().inset(20)
        }
        subtitleLabel.snp.makeConstraints { make in
            make.top.equalTo(titleLabel.snp.bottom).offset(10)
            make.leading.trailing.equalTo(titleLabel)
        }
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
