//
//  CloudDriveFileCell.swift
//  suixinkan
//

import Kingfisher
import SnapKit
import UIKit

/// 云盘文件 Cell，严格对齐 Android 宫格与列表两种样式。
final class CloudDriveFileCell: UICollectionViewCell {
    static let reuseIdentifier = "CloudDriveFileCell"

    /// 点击文件操作入口时回调。
    var onDetails: (() -> Void)?

    private let thumbnailView = UIImageView()
    private let folderIconView = UIImageView(
        image: CloudDriveAsset.image(named: "icon_cloud_storage_folder_type", fallbackSystemName: "folder.fill")
    )
    private let playIconView = UIImageView(
        image: CloudDriveAsset.image(named: "icon_cloud_storage_file_play", fallbackSystemName: "play.circle.fill")
    )
    private let extensionLabel = CloudDrivePaddingLabel()
    private let nameLabel = UILabel()
    private let detailLabel = UILabel()
    private let moreButton = UIButton(type: .system)

    private var gridConstraints: [Constraint] = []
    private var listConstraints: [Constraint] = []

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupUI()
        setupConstraints()
    }

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

    override func prepareForReuse() {
        super.prepareForReuse()
        thumbnailView.kf.cancelDownloadTask()
        thumbnailView.image = nil
        folderIconView.isHidden = true
        playIconView.isHidden = true
        extensionLabel.isHidden = true
        onDetails = nil
    }

    /// 应用云盘文件数据。
    func apply(file: CloudFile, mode: CloudDriveDisplayMode) {
        let isGrid = mode == .grid
        gridConstraints.forEach { isGrid ? $0.activate() : $0.deactivate() }
        listConstraints.forEach { isGrid ? $0.deactivate() : $0.activate() }

        nameLabel.text = file.name
        nameLabel.font = .systemFont(ofSize: 15, weight: isGrid ? .semibold : .regular)
        nameLabel.lineBreakMode = isGrid ? .byTruncatingTail : .byTruncatingMiddle
        detailLabel.text = isGrid ? CloudDriveFormatter.typeName(file.type) : CloudDriveFormatter.fileDescription(file)
        detailLabel.textColor = isGrid ? UIColor(hex: 0x4B5563) : UIColor(hex: 0x7B8EAA)

        contentView.layer.cornerRadius = isGrid ? 12 : 0
        contentView.layer.borderWidth = isGrid ? 1 : 0
        contentView.backgroundColor = isGrid ? .white : .clear
        thumbnailView.layer.cornerRadius = isGrid ? 12 : 0
        thumbnailView.clipsToBounds = isGrid

        configureThumbnail(file, mode: mode)
    }

    private func setupUI() {
        backgroundColor = .clear
        contentView.clipsToBounds = true
        contentView.layer.borderColor = UIColor(hex: 0xF4F4F4).cgColor

        thumbnailView.contentMode = .scaleAspectFill
        thumbnailView.clipsToBounds = true

        folderIconView.contentMode = .scaleAspectFit
        folderIconView.isHidden = true

        playIconView.contentMode = .scaleAspectFit
        playIconView.isHidden = true

        extensionLabel.font = .systemFont(ofSize: 12, weight: .bold)
        extensionLabel.textColor = .white
        extensionLabel.backgroundColor = UIColor.black.withAlphaComponent(0.5)
        extensionLabel.layer.cornerRadius = 4
        extensionLabel.clipsToBounds = true
        extensionLabel.isHidden = true

        nameLabel.textColor = UIColor(hex: 0x333333)
        nameLabel.numberOfLines = 1

        detailLabel.font = .systemFont(ofSize: 12)
        detailLabel.numberOfLines = 1

        let detailsImage = CloudDriveAsset.resizedImage(
            named: "icon_cloud_storage_file_item_details",
            fallbackSystemName: "ellipsis",
            size: CGSize(width: 16, height: 16)
        )
        moreButton.setImage(detailsImage, for: .normal)
        moreButton.imageView?.contentMode = .scaleAspectFit
        moreButton.addTarget(self, action: #selector(moreTapped), for: .touchUpInside)
        moreButton.accessibilityLabel = "文件操作"

        [thumbnailView, folderIconView, playIconView, extensionLabel, nameLabel, detailLabel, moreButton]
            .forEach(contentView.addSubview)
    }

    private func setupConstraints() {
        thumbnailView.snp.makeConstraints { make in
            gridConstraints.append(make.top.leading.trailing.equalToSuperview().constraint)
            gridConstraints.append(make.height.equalTo(thumbnailView.snp.width).dividedBy(1.77).constraint)
            listConstraints.append(make.leading.centerY.equalToSuperview().constraint)
            listConstraints.append(make.width.height.equalTo(48).constraint)
        }
        folderIconView.snp.makeConstraints { make in
            make.center.equalTo(thumbnailView)
            make.width.height.equalTo(48)
        }
        playIconView.snp.makeConstraints { make in
            make.center.equalTo(thumbnailView)
            make.width.height.equalTo(24)
        }
        extensionLabel.snp.makeConstraints { make in
            make.top.leading.equalTo(thumbnailView).offset(8)
        }
        nameLabel.snp.makeConstraints { make in
            gridConstraints.append(make.top.equalTo(thumbnailView.snp.bottom).offset(8).constraint)
            gridConstraints.append(make.leading.equalToSuperview().offset(12).constraint)
            listConstraints.append(make.top.equalToSuperview().offset(12).constraint)
            listConstraints.append(make.leading.equalTo(thumbnailView.snp.trailing).offset(12).constraint)
            make.trailing.equalTo(moreButton.snp.leading).offset(-4)
        }
        detailLabel.snp.makeConstraints { make in
            make.top.equalTo(nameLabel.snp.bottom).offset(2)
            make.leading.trailing.equalTo(nameLabel)
        }
        moreButton.snp.makeConstraints { make in
            gridConstraints.append(make.trailing.equalToSuperview().inset(10).constraint)
            listConstraints.append(make.trailing.equalToSuperview().constraint)
            make.centerY.equalTo(nameLabel.snp.bottom).offset(4)
            make.width.height.equalTo(28)
        }
        listConstraints.forEach { $0.deactivate() }
    }

    private func configureThumbnail(_ file: CloudFile, mode: CloudDriveDisplayMode) {
        thumbnailView.kf.cancelDownloadTask()
        folderIconView.isHidden = true
        playIconView.isHidden = true
        extensionLabel.isHidden = true

        if mode == .list {
            thumbnailView.backgroundColor = .clear
            thumbnailView.contentMode = .scaleAspectFit
            let assetName: String
            let fallbackName: String
            if file.isFolder {
                assetName = "icon_cloud_storage_file_type_folder"
                fallbackName = "folder.fill"
            } else if file.isVideo {
                assetName = "icon_cloud_storage_file_type_video"
                fallbackName = "video.fill"
            } else {
                assetName = "icon_cloud_storage_file_type_photo"
                fallbackName = "photo.fill"
            }
            thumbnailView.image = CloudDriveAsset.image(named: assetName, fallbackSystemName: fallbackName)
            return
        }

        thumbnailView.contentMode = .scaleAspectFill
        if file.isFolder {
            thumbnailView.image = nil
            thumbnailView.backgroundColor = UIColor(hex: 0xFFF0E2)
            folderIconView.isHidden = false
            return
        }

        thumbnailView.backgroundColor = UIColor(hex: 0xF4F4F4)
        let previewURL = file.isVideo ? file.coverUrl : file.fileUrl
        let placeholder = CloudDriveAsset.image(
            named: file.isVideo ? "icon_cloud_storage_file_type_video" : "icon_cloud_storage_file_type_photo",
            fallbackSystemName: file.isVideo ? "video" : "photo"
        )
        if let url = URL(string: previewURL), !previewURL.isEmpty {
            thumbnailView.kf.setImage(with: url, placeholder: placeholder)
        } else {
            thumbnailView.image = placeholder
        }
        playIconView.isHidden = !file.isVideo
        extensionLabel.text = CloudDriveFormatter.fileExtension(file.fileUrl.isEmpty ? file.name : file.fileUrl)
        extensionLabel.isHidden = extensionLabel.text?.isEmpty ?? true
    }

    @objc private func moreTapped() {
        onDetails?()
    }
}

/// 云盘文件扩展名标签，提供 Android 对齐的四边内边距。
private final class CloudDrivePaddingLabel: UILabel {
    private let insets = UIEdgeInsets(top: 4, left: 4, bottom: 4, right: 4)

    override func drawText(in rect: CGRect) {
        super.drawText(in: rect.inset(by: insets))
    }

    override var intrinsicContentSize: CGSize {
        let size = super.intrinsicContentSize
        return CGSize(
            width: size.width + insets.left + insets.right,
            height: size.height + insets.top + insets.bottom
        )
    }
}
