//
//  SampleListViewController.swift
//  suixinkan
//

import Kingfisher
import SnapKit
import UIKit

/// 样片相册列表页，对齐 Android `SampleListScreen`。
final class SampleListViewController: SampleBaseViewController {
    private let viewModel: SampleListViewModel
    private let api: any SampleManagementServing

    private let searchContainer = UIView()
    private let searchBox = UIView()
    private let searchIconView = UIImageView(image: UIImage(systemName: "magnifyingglass"))
    private let searchTextField = UITextField()
    private let filterContainer = UIView()
    private let filterButton = UIButton(type: .system)
    private let filterTitleLabel = UILabel()
    private let filterChevronView = UIImageView(image: UIImage(systemName: "chevron.down"))
    private let filterDropdownView = UIView()
    private let filterDropdownStack = UIStackView()
    private let tableView = UITableView(frame: .zero, style: .plain)
    private let emptyLabel = UILabel()
    private let bottomBar = UIView()
    private let addButton = UIButton(type: .system)
    private var dataSource: UITableViewDiffableDataSource<Int, SampleMaterialItem>!
    private var filterOptionButtons: [(SampleFilterStatus, UIButton)] = []

    /// 初始化样片列表页。
    init(
        viewModel: SampleListViewModel = SampleListViewModel(),
        api: (any SampleManagementServing)? = nil
    ) {
        self.viewModel = viewModel
        self.api = api ?? NetworkServices.shared.sampleManagementAPI
        super.init(nibName: nil, bundle: nil)
    }

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

    override func setupNavigationBar() {
        super.setupNavigationBar()
        setSampleTitle("样片相册列表")
    }

    override func setupUI() {
        super.setupUI()
        view.backgroundColor = SampleManagementUITokens.pageBackground

        searchContainer.backgroundColor = .white
        searchBox.backgroundColor = UIColor(hex: 0xF4F4F4)
        searchBox.layer.cornerRadius = 4
        searchIconView.tintColor = AppColor.textSecondary
        searchIconView.contentMode = .scaleAspectFit
        searchTextField.placeholder = "搜索相册标题"
        searchTextField.font = .systemFont(ofSize: 13)
        searchTextField.textColor = AppColor.textPrimary
        searchTextField.clearButtonMode = .whileEditing
        searchTextField.returnKeyType = .search

        filterContainer.backgroundColor = .white
        filterButton.backgroundColor = UIColor(hex: 0xF4F4F4)
        filterButton.layer.cornerRadius = 4
        filterTitleLabel.text = SampleFilterStatus.all.title
        filterTitleLabel.font = .systemFont(ofSize: 14)
        filterTitleLabel.textColor = UIColor(hex: 0x4B5563)
        filterChevronView.tintColor = UIColor(hex: 0x4B5563)
        filterChevronView.contentMode = .scaleAspectFit
        filterDropdownView.backgroundColor = .white
        filterDropdownView.layer.cornerRadius = 4
        filterDropdownView.layer.shadowColor = UIColor.black.cgColor
        filterDropdownView.layer.shadowOpacity = 0.12
        filterDropdownView.layer.shadowRadius = 10
        filterDropdownView.layer.shadowOffset = CGSize(width: 0, height: 4)
        filterDropdownView.isHidden = true
        filterDropdownStack.axis = .vertical
        filterDropdownStack.spacing = 0

        tableView.backgroundColor = SampleManagementUITokens.pageBackground
        tableView.separatorStyle = .none
        tableView.estimatedRowHeight = 152
        tableView.rowHeight = UITableView.automaticDimension
        tableView.delegate = self
        tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 16, right: 0)
        tableView.register(SampleListCell.self, forCellReuseIdentifier: SampleListCell.reuseIdentifier)
        tableView.refreshControl = UIRefreshControl()

        dataSource = UITableViewDiffableDataSource<Int, SampleMaterialItem>(tableView: tableView) {
            [weak self] tableView, indexPath, item in
            let cell = tableView.dequeueReusableCell(
                withIdentifier: SampleListCell.reuseIdentifier,
                for: indexPath
            ) as! SampleListCell
            cell.apply(item: item)
            cell.onToggle = { [weak self] checked in
                guard let self else { return }
                Task { await self.viewModel.toggleListing(sampleId: item.id, checked: checked, api: self.api) }
            }
            return cell
        }

        emptyLabel.text = "暂无样片"
        emptyLabel.font = .systemFont(ofSize: 16)
        emptyLabel.textColor = AppColor.textSecondary
        emptyLabel.textAlignment = .center
        emptyLabel.isHidden = true

        bottomBar.backgroundColor = .white
        addButton.setTitle("添加", for: .normal)
        addButton.setTitleColor(.white, for: .normal)
        addButton.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
        addButton.backgroundColor = AppColor.primary
        addButton.layer.cornerRadius = 8

        view.addSubview(searchContainer)
        searchContainer.addSubview(searchBox)
        searchBox.addSubview(searchIconView)
        searchBox.addSubview(searchTextField)
        view.addSubview(filterContainer)
        filterContainer.addSubview(filterButton)
        filterButton.addSubview(filterTitleLabel)
        filterButton.addSubview(filterChevronView)
        view.addSubview(tableView)
        view.addSubview(emptyLabel)
        view.addSubview(bottomBar)
        bottomBar.addSubview(addButton)
        view.addSubview(filterDropdownView)
        filterDropdownView.addSubview(filterDropdownStack)
        configureFilterDropdown()
    }

    override func setupConstraints() {
        searchContainer.snp.makeConstraints { make in
            make.top.equalTo(view.safeAreaLayoutGuide)
            make.leading.trailing.equalToSuperview()
            make.height.equalTo(68)
        }
        searchBox.snp.makeConstraints { make in
            make.leading.trailing.equalToSuperview().inset(16)
            make.centerY.equalToSuperview()
            make.height.equalTo(36)
        }
        searchIconView.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(12)
            make.centerY.equalToSuperview()
            make.size.equalTo(15)
        }
        searchTextField.snp.makeConstraints { make in
            make.leading.equalTo(searchIconView.snp.trailing).offset(12)
            make.trailing.equalToSuperview().inset(12)
            make.top.bottom.equalToSuperview()
        }
        filterContainer.snp.makeConstraints { make in
            make.top.equalTo(searchContainer.snp.bottom).offset(1)
            make.leading.trailing.equalToSuperview()
            make.height.equalTo(68)
        }
        filterButton.snp.makeConstraints { make in
            make.leading.trailing.equalToSuperview().inset(16)
            make.centerY.equalToSuperview()
            make.height.equalTo(36)
        }
        filterTitleLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(16)
            make.centerY.equalToSuperview()
        }
        filterChevronView.snp.makeConstraints { make in
            make.trailing.equalToSuperview().inset(14)
            make.centerY.equalToSuperview()
            make.size.equalTo(18)
        }
        bottomBar.snp.makeConstraints { make in
            make.leading.trailing.bottom.equalToSuperview()
        }
        addButton.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(16)
            make.leading.trailing.equalToSuperview().inset(15)
            make.height.equalTo(48)
            make.bottom.equalTo(view.safeAreaLayoutGuide).offset(-16)
        }
        tableView.snp.makeConstraints { make in
            make.top.equalTo(filterContainer.snp.bottom).offset(12)
            make.leading.trailing.equalToSuperview()
            make.bottom.equalTo(bottomBar.snp.top)
        }
        filterDropdownView.snp.makeConstraints { make in
            make.top.equalTo(filterButton.snp.bottom)
            make.leading.trailing.equalTo(filterButton)
        }
        filterDropdownStack.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        emptyLabel.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.centerY.equalTo(tableView)
            make.leading.trailing.equalToSuperview().inset(24)
        }
    }

    override func bindActions() {
        viewModel.onStateChange = { [weak self] in
            Task { @MainActor in self?.applyViewModel() }
        }
        viewModel.onShowMessage = { [weak self] message in
            Task { @MainActor in self?.showToast(message) }
        }
        searchTextField.addTarget(self, action: #selector(searchTextChanged), for: .editingChanged)
        searchTextField.delegate = self
        filterButton.addTarget(self, action: #selector(filterTapped), for: .touchUpInside)
        addButton.addTarget(self, action: #selector(addTapped), for: .touchUpInside)
        tableView.refreshControl?.addTarget(self, action: #selector(refreshPulled), for: .valueChanged)
    }

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

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if needsRefreshOnAppear {
            needsRefreshOnAppear = false
            Task { await viewModel.refresh(api: api) }
        }
    }

    private var needsRefreshOnAppear = false

    @MainActor
    private func applyViewModel() {
        filterTitleLabel.text = viewModel.filterStatus.title
        filterOptionButtons.forEach { status, button in
            let selected = status == viewModel.filterStatus
            button.setTitleColor(selected ? AppColor.primary : AppColor.textPrimary, for: .normal)
            button.titleLabel?.font = .systemFont(ofSize: 14, weight: selected ? .medium : .regular)
        }
        if searchTextField.text != viewModel.searchText {
            searchTextField.text = viewModel.searchText
        }

        var snapshot = NSDiffableDataSourceSnapshot<Int, SampleMaterialItem>()
        snapshot.appendSections([0])
        snapshot.appendItems(viewModel.items)
        dataSource.apply(snapshot, animatingDifferences: true)
        emptyLabel.isHidden = !viewModel.items.isEmpty || viewModel.isLoading || viewModel.isRefreshing
        viewModel.isLoading && viewModel.items.isEmpty ? showLoading() : hideLoading()
        if !viewModel.isRefreshing {
            tableView.refreshControl?.endRefreshing()
        }
    }

    @objc private func searchTextChanged() {
        let text = searchTextField.text ?? ""
        Task { await viewModel.updateSearchText(text, api: api) }
    }

    @objc private func filterTapped() {
        filterDropdownView.isHidden.toggle()
        view.bringSubviewToFront(filterDropdownView)
        UIView.animate(withDuration: 0.2) {
            self.filterChevronView.transform = self.filterDropdownView.isHidden
                ? .identity
                : CGAffineTransform(rotationAngle: .pi)
        }
    }

    @objc private func addTapped() {
        let controller = UploadSampleViewController()
        controller.onUploadSuccess = { [weak self] in
            self?.needsRefreshOnAppear = true
        }
        navigationController?.pushViewController(controller, animated: true)
    }

    @objc private func refreshPulled() {
        hideFilterDropdown()
        Task { await viewModel.refresh(api: api) }
    }

    private func configureFilterDropdown() {
        SampleFilterStatus.allCases.forEach { status in
            let button = UIButton(type: .system)
            button.contentHorizontalAlignment = .leading
            button.setConfigurationContentInsets(
                NSDirectionalEdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16)
            )
            button.setTitle(status.title, for: .normal)
            button.backgroundColor = .white
            button.snp.makeConstraints { make in
                make.height.equalTo(48)
            }
            button.addAction(UIAction { [weak self] _ in
                guard let self else { return }
                self.hideFilterDropdown()
                Task { await self.viewModel.selectFilter(status, api: self.api) }
            }, for: .touchUpInside)
            filterDropdownStack.addArrangedSubview(button)
            filterOptionButtons.append((status, button))
        }
    }

    private func hideFilterDropdown() {
        guard !filterDropdownView.isHidden else { return }
        filterDropdownView.isHidden = true
        UIView.animate(withDuration: 0.2) {
            self.filterChevronView.transform = .identity
        }
    }
}

extension SampleListViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        hideFilterDropdown()
        tableView.deselectRow(at: indexPath, animated: true)
        guard let item = dataSource.itemIdentifier(for: indexPath) else { return }
        navigationController?.pushViewController(SampleDetailViewController(sampleId: item.id), animated: true)
    }

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        Task { await viewModel.loadMoreIfNeeded(lastVisibleIndex: indexPath.row, api: api) }
    }
}

extension SampleListViewController: UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
}

/// 样片列表卡片 cell，对齐 Android `SampleItemView`。
private final class SampleListCell: UITableViewCell {
    static let reuseIdentifier = "SampleListCell"

    private let cardView = UIView()
    private let coverImageView = UIImageView()
    private let placeholderLabel = UILabel()
    private let titleLabel = UILabel()
    private let projectLabel = UILabel()
    private let scenicSpotLabel = UILabel()
    private let statusBadge = SampleStatusBadgeView()
    private let listingSwitch = UISwitch()
    private let statsStack = UIStackView()
    private let shareStatView = SampleStatView(iconName: "sample_ic_share_count")
    private let likeStatView = SampleStatView(iconName: "sample_ic_like_count")
    private let collectStatView = SampleStatView(iconName: "sample_ic_collect_count")
    private var isApplying = false
    private var confirmedListingState = false

    var onToggle: ((Bool) -> Void)?

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        setupUI()
    }

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

    override func prepareForReuse() {
        super.prepareForReuse()
        onToggle = nil
    }

    func apply(item: SampleMaterialItem) {
        isApplying = true
        confirmedListingState = item.listingStatus == 1
        titleLabel.text = item.name
        projectLabel.text = "项目: \(item.projectName)"
        scenicSpotLabel.text = "打卡地: \(item.scenicSpotName)"
        statusBadge.apply(status: item.status)
        listingSwitch.setOn(confirmedListingState, animated: false)
        shareStatView.setCount(item.shareCount)
        likeStatView.setCount(item.likesCount)
        collectStatView.setCount(item.collectCount)

        if let url = URL(string: item.coverUrl), !item.coverUrl.isEmpty {
            placeholderLabel.isHidden = true
            coverImageView.kf.setImage(with: url)
        } else {
            coverImageView.image = nil
            placeholderLabel.isHidden = false
        }
        isApplying = false
    }

    private func setupUI() {
        selectionStyle = .none
        backgroundColor = SampleManagementUITokens.pageBackground
        contentView.backgroundColor = SampleManagementUITokens.pageBackground

        cardView.backgroundColor = .white
        cardView.layer.cornerRadius = 12
        cardView.clipsToBounds = true

        coverImageView.backgroundColor = UIColor(hex: 0xF5F5F5)
        coverImageView.contentMode = .scaleAspectFill
        coverImageView.clipsToBounds = true
        coverImageView.layer.cornerRadius = 8

        placeholderLabel.text = "暂无图片"
        placeholderLabel.font = .systemFont(ofSize: 12)
        placeholderLabel.textColor = AppColor.textSecondary
        placeholderLabel.textAlignment = .center

        titleLabel.font = .systemFont(ofSize: 16, weight: .bold)
        titleLabel.textColor = .black
        titleLabel.numberOfLines = 1

        [projectLabel, scenicSpotLabel].forEach { label in
            label.font = .systemFont(ofSize: 12)
            label.textColor = UIColor(hex: 0x4B5563)
            label.numberOfLines = 1
        }

        listingSwitch.onTintColor = AppColor.primary
        listingSwitch.accessibilityLabel = "样片上下架"
        listingSwitch.addTarget(self, action: #selector(switchChanged), for: .valueChanged)

        statsStack.axis = .horizontal
        statsStack.spacing = 16
        statsStack.alignment = .center

        contentView.addSubview(cardView)
        cardView.addSubview(coverImageView)
        coverImageView.addSubview(placeholderLabel)
        cardView.addSubview(titleLabel)
        cardView.addSubview(projectLabel)
        cardView.addSubview(scenicSpotLabel)
        cardView.addSubview(statusBadge)
        cardView.addSubview(listingSwitch)
        cardView.addSubview(statsStack)
        [shareStatView, likeStatView, collectStatView].forEach(statsStack.addArrangedSubview)

        cardView.snp.makeConstraints { make in
            make.top.equalToSuperview()
            make.bottom.equalToSuperview().inset(16)
            make.leading.trailing.equalToSuperview().inset(16)
        }
        coverImageView.snp.makeConstraints { make in
            make.leading.top.bottom.equalToSuperview().inset(12)
            make.size.equalTo(128)
        }
        placeholderLabel.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.leading.trailing.equalToSuperview().inset(8)
        }
        titleLabel.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(16)
            make.leading.equalTo(coverImageView.snp.trailing).offset(12)
            make.trailing.equalToSuperview().inset(12)
        }
        projectLabel.snp.makeConstraints { make in
            make.top.equalTo(titleLabel.snp.bottom).offset(8)
            make.leading.trailing.equalTo(titleLabel)
        }
        scenicSpotLabel.snp.makeConstraints { make in
            make.top.equalTo(projectLabel.snp.bottom).offset(6)
            make.leading.trailing.equalTo(titleLabel)
        }
        statusBadge.snp.makeConstraints { make in
            make.top.equalTo(scenicSpotLabel.snp.bottom).offset(10)
            make.leading.equalTo(titleLabel)
            make.height.equalTo(24)
        }
        listingSwitch.snp.makeConstraints { make in
            make.centerY.equalTo(statusBadge)
            make.trailing.equalToSuperview().inset(12)
            make.leading.greaterThanOrEqualTo(statusBadge.snp.trailing).offset(8)
        }
        statsStack.snp.makeConstraints { make in
            make.top.equalTo(statusBadge.snp.bottom).offset(10)
            make.leading.equalTo(titleLabel)
            make.trailing.lessThanOrEqualToSuperview().inset(12)
            make.bottom.lessThanOrEqualToSuperview().inset(12)
        }
    }

    @objc private func switchChanged() {
        guard !isApplying else { return }
        let requestedState = listingSwitch.isOn
        listingSwitch.setOn(confirmedListingState, animated: true)
        onToggle?(requestedState)
    }
}

/// 样片状态 badge。
final class SampleStatusBadgeView: UIView {
    private let label = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)
        layer.cornerRadius = 4
        addSubview(label)
        label.font = .systemFont(ofSize: 12, weight: .medium)
        label.snp.makeConstraints { make in
            make.leading.trailing.equalToSuperview().inset(6)
            make.centerY.equalToSuperview()
        }
    }

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

    /// 设置审核状态。
    func apply(status: Int) {
        let color: UIColor
        switch status {
        case 1: color = UIColor(hex: 0x22C55E)
        case 0: color = UIColor(hex: 0xFF7B00)
        case 2: color = UIColor(hex: 0xEF4444)
        default: color = AppColor.textSecondary
        }
        label.text = SampleDisplayFormatter.reviewStatusText(status)
        label.textColor = color
        backgroundColor = color.withAlphaComponent(0.1)
    }
}

/// 样片统计图标与数字。
private final class SampleStatView: UIView {
    private let iconView = UIImageView()
    private let countLabel = UILabel()

    init(iconName: String) {
        super.init(frame: .zero)
        iconView.image = UIImage(named: iconName)
        iconView.tintColor = UIColor(hex: 0x6B7280)
        iconView.contentMode = .scaleAspectFit
        countLabel.font = .systemFont(ofSize: 14)
        countLabel.textColor = UIColor(hex: 0x6B7280)
        addSubview(iconView)
        addSubview(countLabel)
        iconView.snp.makeConstraints { make in
            make.leading.centerY.equalToSuperview()
            make.size.equalTo(16)
        }
        countLabel.snp.makeConstraints { make in
            make.leading.equalTo(iconView.snp.trailing).offset(4)
            make.trailing.centerY.equalToSuperview()
        }
    }

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

    func setCount(_ count: Int) {
        countLabel.text = SampleDisplayFormatter.formatCount(count)
    }
}
