//
//  HomeLocationReportCardView.swift
//  suixinkan
//

import SnapKit
import UIKit

/// 首页位置上报卡片。
final class HomeLocationReportCardView: UIView {

    var onReportTap: (() -> Void)?

    private let contentStackView = UIStackView()
    private let titleStackView = UIStackView()
    private let titleIconView = UIImageView(image: UIImage(systemName: "arrow.up.square.fill"))
    private let titleLabel = UILabel()
    private let addressLabel = UILabel()
    private let reportButtonContainer = UIView()
    private let reportButton = UIButton(type: .system)
    private let reportGradientLayer = CAGradientLayer()

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = AppColor.cardBackground
        layer.cornerRadius = AppRadius.lg
        layer.borderWidth = 1
        layer.borderColor = AppColor.cardOutline.cgColor
        clipsToBounds = true

        contentStackView.axis = .vertical
        contentStackView.alignment = .fill
        contentStackView.spacing = AppSpacing.xxs

        titleStackView.axis = .horizontal
        titleStackView.alignment = .center
        titleStackView.spacing = AppSpacing.xs

        titleIconView.tintColor = AppColor.primary
        titleIconView.contentMode = .scaleAspectFit

        titleLabel.text = "立即上报"
        titleLabel.font = .systemFont(ofSize: 24, weight: .bold)
        titleLabel.textColor = AppColor.textPrimary

        addressLabel.font = .app(.subtitle)
        addressLabel.textColor = AppColor.textTertiary
        addressLabel.numberOfLines = 2

        reportGradientLayer.colors = [AppColor.primary.cgColor, AppColor.primaryGradientEnd.cgColor]
        reportGradientLayer.startPoint = CGPoint(x: 0.5, y: 0)
        reportGradientLayer.endPoint = CGPoint(x: 0.5, y: 1)
        reportButtonContainer.layer.insertSublayer(reportGradientLayer, at: 0)
        reportButtonContainer.layer.cornerRadius = 46
        reportButtonContainer.clipsToBounds = true

        reportButton.backgroundColor = .clear
        reportButton.tintColor = .white
        reportButton.setImage(UIImage(systemName: "hand.tap.fill"), for: .normal)
        reportButton.setPreferredSymbolConfiguration(
            UIImage.SymbolConfiguration(pointSize: 38, weight: .semibold),
            forImageIn: .normal
        )
        reportButton.imageView?.contentMode = .scaleAspectFit
        reportButton.isExclusiveTouch = true
        reportButton.addTarget(self, action: #selector(reportTouchDown), for: .touchDown)
        reportButton.addTarget(self, action: #selector(reportTouchUpInside), for: .touchUpInside)
        reportButton.addTarget(self, action: #selector(reportTouchEnded), for: [.touchUpOutside, .touchCancel, .touchDragExit])
        reportButton.accessibilityLabel = "上报位置"

        titleStackView.addArrangedSubview(titleIconView)
        titleStackView.addArrangedSubview(titleLabel)
        contentStackView.addArrangedSubview(titleStackView)
        contentStackView.addArrangedSubview(addressLabel)
        addSubview(contentStackView)
        addSubview(reportButtonContainer)
        reportButtonContainer.addSubview(reportButton)

        titleIconView.snp.makeConstraints { make in
            make.width.height.equalTo(25)
        }
        contentStackView.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(AppSpacing.md)
            make.centerY.equalTo(reportButtonContainer)
            make.trailing.equalTo(reportButtonContainer.snp.leading).offset(-AppSpacing.sm)
            make.top.greaterThanOrEqualToSuperview().offset(AppSpacing.md)
            make.bottom.lessThanOrEqualToSuperview().offset(-AppSpacing.md)
        }
        reportButtonContainer.snp.makeConstraints { make in
            make.trailing.equalToSuperview().offset(-AppSpacing.md)
            make.centerY.equalToSuperview()
            make.width.height.equalTo(96)
        }
        reportButton.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
    }

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

    override func layoutSubviews() {
        super.layoutSubviews()
        reportGradientLayer.frame = reportButtonContainer.bounds
        reportGradientLayer.cornerRadius = reportButtonContainer.bounds.width / 2
    }

    func apply(address: String, isReporting: Bool) {
        addressLabel.text = address
        reportButton.isEnabled = !isReporting
        reportButton.alpha = 1
        if isReporting {
            resetReportButtonScale()
        }
        reportGradientLayer.colors = isReporting
            ? [AppColor.controlDisabledStart.cgColor, AppColor.controlDisabledEnd.cgColor]
            : [AppColor.primary.cgColor, AppColor.primaryGradientEnd.cgColor]
    }

    @objc private func reportTouchDown() {
        animateReportButtonScale(isPressed: true)
        playCenteredRipple()
    }

    @objc private func reportTouchUpInside() {
        animateReportButtonScale(isPressed: false)
        onReportTap?()
    }

    @objc private func reportTouchEnded() {
        animateReportButtonScale(isPressed: false)
    }

    private func playCenteredRipple() {
        reportButtonContainer.layer.sublayers?
            .filter { $0.name == "HomeLocationReportRippleLayer" }
            .forEach { $0.removeFromSuperlayer() }

        let diameter = max(reportButtonContainer.bounds.width, reportButtonContainer.bounds.height) * 1.45
        let rippleLayer = CALayer()
        rippleLayer.name = "HomeLocationReportRippleLayer"
        rippleLayer.backgroundColor = UIColor.white.withAlphaComponent(0.28).cgColor
        rippleLayer.bounds = CGRect(x: 0, y: 0, width: diameter, height: diameter)
        rippleLayer.cornerRadius = diameter / 2
        rippleLayer.position = CGPoint(x: reportButtonContainer.bounds.midX, y: reportButtonContainer.bounds.midY)
        rippleLayer.transform = CATransform3DMakeScale(0.18, 0.18, 1)
        rippleLayer.opacity = 0.32
        reportButtonContainer.layer.insertSublayer(rippleLayer, below: reportButton.layer)

        let scaleAnimation = CABasicAnimation(keyPath: "transform.scale")
        scaleAnimation.fromValue = 0.18
        scaleAnimation.toValue = 1

        let opacityAnimation = CABasicAnimation(keyPath: "opacity")
        opacityAnimation.fromValue = 0.32
        opacityAnimation.toValue = 0

        let group = CAAnimationGroup()
        group.animations = [scaleAnimation, opacityAnimation]
        group.duration = 0.55
        group.timingFunction = CAMediaTimingFunction(name: .easeOut)
        group.isRemovedOnCompletion = false
        group.fillMode = .forwards

        CATransaction.begin()
        CATransaction.setCompletionBlock { [weak rippleLayer] in
            rippleLayer?.removeFromSuperlayer()
        }
        rippleLayer.add(group, forKey: "centeredRipple")
        CATransaction.commit()
    }

    private func animateReportButtonScale(isPressed: Bool) {
        UIView.animate(
            withDuration: isPressed ? 0.12 : 0.18,
            delay: 0,
            options: [.beginFromCurrentState, .curveEaseOut]
        ) {
            self.reportButtonContainer.transform = isPressed
                ? CGAffineTransform(scaleX: 0.96, y: 0.96)
                : .identity
        }
    }

    private func resetReportButtonScale() {
        reportButtonContainer.layer.removeAllAnimations()
        reportButtonContainer.transform = .identity
    }
}
