import UIKit
import SwiftUI

/// Animated typing dots indicator matching Telegram iOS exactly.
/// Uses CADisplayLink for smooth animation of 3 pulsing dots.
///
/// Reference: Telegram-iOS `ChatTypingActivityContentNode.swift`
/// - minDiameter: 3.0, maxDiameter: 4.5
/// - duration: 0.7s, timeOffsets: [0.4, 0.2, 0.0]
/// - alpha range: 0.75–1.0
/// - total size: 24×16
final class TypingDotsView: UIView {

    var dotColor: UIColor = UIColor(red: 0x8E/255, green: 0x8E/255, blue: 0x93/255, alpha: 1) {
        didSet { setNeedsDisplay() }
    }

    private var displayLink: CADisplayLink?
    private var startTime: CFTimeInterval = 0

    // Telegram-exact constants
    private let animDuration: CFTimeInterval = 0.7
    private let minD: CGFloat = 3.0
    private let maxD: CGFloat = 4.5
    private let dotDistance: CGFloat = 5.5  // 11.0 / 2.0
    private let leftPad: CGFloat = 6.0
    private let minAlpha: CGFloat = 0.75
    private let deltaAlpha: CGFloat = 0.25  // 1.0 - 0.75
    private let timeOffsets: [CGFloat] = [0.4, 0.2, 0.0]

    override init(frame: CGRect) {
        super.init(frame: frame)
        isOpaque = false
        backgroundColor = .clear
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    deinit {
        displayLink?.invalidate()
    }

    func startAnimating() {
        guard displayLink == nil else { return }
        startTime = CACurrentMediaTime()
        let link = CADisplayLink(target: self, selector: #selector(tick))
        link.add(to: .main, forMode: .common)
        displayLink = link
    }

    func stopAnimating() {
        displayLink?.invalidate()
        displayLink = nil
    }

    @objc private func tick() {
        setNeedsDisplay()
    }

    override func draw(_ rect: CGRect) {
        guard let ctx = UIGraphicsGetCurrentContext() else { return }

        let progress = CGFloat(fmod(CACurrentMediaTime() - startTime, animDuration) / animDuration)
        let centerY = rect.height / 2

        for (i, offset) in timeOffsets.enumerated() {
            var r = radiusFunc(progress, timeOffset: offset)
            r = (max(minD, r) - minD) / (maxD - minD) * 1.5

            let alpha = (r * deltaAlpha + minAlpha)
            ctx.setFillColor(dotColor.withAlphaComponent(alpha).cgColor)

            let x = leftPad + CGFloat(i) * dotDistance
            let size = minD + r
            ctx.fillEllipse(in: CGRect(
                x: x - size / 2,
                y: centerY - size / 2,
                width: size,
                height: size
            ))
        }
    }

    // Telegram-exact radius function (ChatTypingActivityContentNode.swift)
    private func radiusFunc(_ value: CGFloat, timeOffset: CGFloat) -> CGFloat {
        var v = value + timeOffset
        if v > 1.0 { v -= floor(v) }
        if v < 0.4 {
            return (1.0 - v / 0.4) * minD + (v / 0.4) * maxD
        } else if v < 0.8 {
            return (1.0 - (v - 0.4) / 0.4) * maxD + ((v - 0.4) / 0.4) * minD
        }
        return minD
    }
}

// MARK: - SwiftUI Bridge

/// SwiftUI wrapper for TypingDotsView — used in ChatDetail toolbar capsule.
struct TypingDotsRepresentable: UIViewRepresentable {
    let color: UIColor

    func makeUIView(context: Context) -> TypingDotsView {
        let view = TypingDotsView()
        view.dotColor = color
        view.startAnimating()
        return view
    }

    func updateUIView(_ view: TypingDotsView, context: Context) {
        view.dotColor = color
    }
}
