//
//  AV_WaveView.swift
//  anniversary_Project
//
//  Created by 忆海16 on 2024/7/8.
//

import UIKit

class AV_WaveView: UIView {

    private var waveLayers: [CAShapeLayer] = []
    private var waveHeight: CGFloat = 10.0
    private var waveLength: CGFloat = 200.0
    private var waveSpeed: CGFloat = 0.05
    private var waveOffset: CGFloat = 0.0
    private var wavePositionY: CGFloat = 0.0
    private var totalCapacity: CGFloat = 0.0
    private var currentVolume: CGFloat = 0.0
    private var timer: Timer?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupWaveLayers()
        setupMaskLayer()
        startWaveAnimation()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupWaveLayers()
        setupMaskLayer()
        startWaveAnimation()
    }
    
    private func setupWaveLayers() {
        let colors = [UIColor.hexSting(color: "#96D3FF", alpha: 1).cgColor,
                      UIColor.hexSting(color: "#62BFFF", alpha: 1).cgColor]
        for color in colors {
            let waveLayer = CAShapeLayer()
            waveLayer.fillColor = color
            layer.addSublayer(waveLayer)
            waveLayers.append(waveLayer)
        }
    }
    
    private func setupMaskLayer() {
        let maskLayer = CAShapeLayer()
        let path = UIBezierPath(rect: bounds)
        maskLayer.path = path.cgPath
        layer.mask = maskLayer
    }
    
    private func startWaveAnimation() {
        timer = Timer.scheduledTimer(timeInterval: 1.0 / 30.0, target: self, selector: #selector(updateWave), userInfo: nil, repeats: true)
    }
    
    @objc private func updateWave() {
        waveOffset += waveSpeed
        for (index, waveLayer) in waveLayers.enumerated() {
            let amplitude = waveHeight * (1.2 - 0.2 * CGFloat(index))
            let path = createWavePath(offset: waveOffset + CGFloat(index) * 0.3, amplitude: amplitude)
            waveLayer.path = path.cgPath
        }
    }
    
    private func createWavePath(offset: CGFloat, amplitude: CGFloat) -> UIBezierPath {
        let path = UIBezierPath()
        let width = bounds.width
        let height = bounds.height
        let midY = height * wavePositionY
        path.move(to: CGPoint(x: 0, y: midY))
        
        for x in stride(from: 0.0, to: Double(width), by: 1.0) {
            let relativeX = CGFloat(x) / waveLength * .pi * 2
            let y = sin(relativeX + offset) * amplitude + midY
            path.addLine(to: CGPoint(x: CGFloat(x), y: y))
        }
        
        path.addLine(to: CGPoint(x: width, y: height))
        path.addLine(to: CGPoint(x: 0, y: height))
        path.close()
        
        return path
    }
    
    func setTotalCapacity(_ capacity: CGFloat) {
        totalCapacity = capacity
        currentVolume = 0
        wavePositionY = 1.0
        updateWavePosition(animated: false)
    }
    
    func drinkWater(_ volume: CGFloat) {
        currentVolume += volume
        if currentVolume > totalCapacity {
            currentVolume = totalCapacity
        }
        
        let newPositionY = 1.0 - (currentVolume / totalCapacity)
        updateWavePosition(animated: true, targetPositionY: newPositionY)
    }
    
    func setCurrentVolume(_ volume: CGFloat) {
          currentVolume = volume
          if currentVolume > totalCapacity {
              currentVolume = totalCapacity
          } else if currentVolume < 0 {
              currentVolume = 0
          }
          
          let newPositionY = 1.0 - (currentVolume / totalCapacity)
          updateWavePosition(animated: true, targetPositionY: newPositionY)
      }
    
    private func updateWavePosition(animated: Bool, targetPositionY: CGFloat? = nil) {
        let newPositionY = targetPositionY ?? (1.0 - (currentVolume / totalCapacity))
        
        if animated {
            UIView.animate(withDuration: 3.0, delay: 0, options: [.curveEaseInOut], animations: {
                self.wavePositionY = newPositionY
                self.layer.setNeedsDisplay()
            }, completion: { finished in
                if finished {
                    print("Animation completed.")
                }
            })
        } else {
            wavePositionY = newPositionY
            layer.setNeedsDisplay()
        }
    }
    
    deinit {
        timer?.invalidate()
    }
}
