//! 动画系统：眨眼、嘴部动效、待机呼吸

use super::core_ffi::CubismCore;
use super::model::CubismModel;
use std::time::{Duration, Instant};

/// 动画状态
pub struct AnimationState {
    /// 眨眼定时器
    last_blink: Instant,
    next_blink_interval: Duration,
    blink_phase: BlinkPhase,
    /// 嘴部状态
    talking: bool,
    mouth_open: f32,
    mouth_target: f32,
    last_mouth_update: Instant,
    /// 呼吸
    breath_phase: f32,
    /// 身体摇摆
    body_phase: f32,
    /// 眼球跟随（简化为固定值）
    eye_ball_x: f32,
    eye_ball_y: f32,
}

#[derive(Clone, Copy, Debug)]
enum BlinkPhase {
    Idle,
    Closing(f32),  // 0→1
    Opening(f32),  // 1→0
}

impl Default for AnimationState {
    fn default() -> Self {
        Self {
            last_blink: Instant::now(),
            next_blink_interval: Duration::from_secs(3),
            blink_phase: BlinkPhase::Idle,
            talking: false,
            mouth_open: 0.0,
            mouth_target: 0.0,
            last_mouth_update: Instant::now(),
            breath_phase: 0.0,
            body_phase: 0.0,
            eye_ball_x: 0.0,
            eye_ball_y: 0.0,
        }
    }
}

impl AnimationState {
    pub fn set_talking(&mut self, talking: bool) {
        self.talking = talking;
        if !talking {
            self.mouth_target = 0.0;
        }
    }

    /// 更新动画并应用到 model 参数
    pub fn update(&mut self, core: &CubismCore, model: &CubismModel, now: Instant, dt: f32) {
        // === 呼吸 ===
        self.breath_phase += dt * 0.5; // 0.5 Hz
        let breath = self.breath_phase.sin() * 0.5 + 0.5;
        model.set_param(core, "ParamBreath", breath);

        // === 身体摇摆 ===
        self.body_phase += dt * 0.3;
        let body_x = self.body_phase.sin() * 8.0;
        let body_y = self.body_phase.sin() * 0.5;
        model.set_param(core, "ParamBodyAngleX", body_x);
        model.set_param(core, "ParamBodyAngleY", body_y);

        // === 眨眼 ===
        self.update_blink(now, core, model);

        // === 嘴部 ===
        self.update_mouth(now, dt, core, model);

        // === 眼球（轻微随机移动）===
        self.eye_ball_x = (now.elapsed().as_secs_f32() * 0.3).sin() * 0.3;
        self.eye_ball_y = (now.elapsed().as_secs_f32() * 0.2).cos() * 0.2;
        model.set_param(core, "ParamEyeBallX", self.eye_ball_x);
        model.set_param(core, "ParamEyeBallY", self.eye_ball_y);
    }

    fn update_blink(&mut self, now: Instant, core: &CubismCore, model: &CubismModel) {
        // 先计算新的眨眼状态和当前 eye_open 值，避免借用冲突
        let (new_phase, eye_open) = match self.blink_phase {
            BlinkPhase::Idle => {
                if now.duration_since(self.last_blink) >= self.next_blink_interval {
                    (BlinkPhase::Closing(0.0), 1.0)
                } else {
                    (BlinkPhase::Idle, 1.0)
                }
            }
            BlinkPhase::Closing(mut t) => {
                t += 0.15;
                if t >= 1.0 {
                    (BlinkPhase::Opening(1.0), 0.0)
                } else {
                    (BlinkPhase::Closing(t), 1.0 - t)
                }
            }
            BlinkPhase::Opening(mut t) => {
                t -= 0.1;
                if t <= 0.0 {
                    self.last_blink = now;
                    self.next_blink_interval =
                        Duration::from_secs(2 + (now.elapsed().as_nanos() % 3) as u64);
                    (BlinkPhase::Idle, 1.0)
                } else {
                    (BlinkPhase::Opening(t), 1.0 - t)
                }
            }
        };
        self.blink_phase = new_phase;
        model.set_param(core, "ParamEyeLOpen", eye_open);
        model.set_param(core, "ParamEyeROpen", eye_open);
    }

    fn update_mouth(
        &mut self,
        now: Instant,
        dt: f32,
        core: &CubismCore,
        model: &CubismModel,
    ) {
        if self.talking {
            // 说话时嘴部快速开合
            let t = now.elapsed().as_secs_f32();
            // 用多个正弦叠加产生自然的变化
            let base = (t * 12.0).sin() * 0.4 + (t * 7.0).sin() * 0.3 + (t * 19.0).sin() * 0.2;
            self.mouth_target = (base * 0.5 + 0.5).clamp(0.0, 1.0) * 0.9 + 0.1;
        } else {
            self.mouth_target = 0.0;
        }

        // 平滑过渡
        let lerp_speed = 15.0 * dt;
        self.mouth_open += (self.mouth_target - self.mouth_open) * lerp_speed.min(1.0);
        model.set_param(core, "ParamMouthOpenY", self.mouth_open);

        // 嘴部形态也轻微变化
        let form = (now.elapsed().as_secs_f32() * 3.0).sin() * 0.3 * if self.talking { 1.0 } else { 0.0 };
        model.set_param(core, "ParamMouthForm", form);
    }
}
