import React, { useEffect, useRef } from "react";
import { microphoneConfigs, MicrophoneOptions, useMicrophone, VolumeData } from "../../../hooks";
import { Panel } from "./styled";

const MicrophoneAnimation: React.FC<{ isStarting?: boolean }> = ({ isStarting }) => {
  const canvasRef = useRef<HTMLCanvasElement | null>(null);
  const panelRef = useRef<HTMLDivElement | null>(null);
  const barsRef = useRef<number[]>([]);
  const lastBarTimeRef = useRef(0);
  const animationIdRef = useRef<any>(null);
  const volumeRef = useRef(0);

  // 常量配置
  const LEFT_NEW_BAR_MS = 50;
  const LEFT_MAX_H = 160;
  const LEFT_MIN_H = 4;
  // const LEFT_GAIN = 2.2;

  // 工具函数
  const clamp = (v: number, a = 0, b = 1) => Math.max(a, Math.min(b, v));

  // 获取用户音量输入
  const getLeftLevelFromUser = () => {
    if (typeof volumeRef.current === "number") return clamp(volumeRef.current);
    return null;
  };

  // 绘制圆角矩形
  const roundRect = (
    ctx: CanvasRenderingContext2D,
    x: number,
    y: number,
    w: number,
    h: number,
    r: number
  ) => {
    const radius = Math.min(r, w / 2, h / 2);
    ctx.beginPath();
    ctx.moveTo(x + radius, y);
    ctx.lineTo(x + w - radius, y);
    ctx.quadraticCurveTo(x + w, y, x + w, y + radius);
    ctx.lineTo(x + w, y + h - radius);
    ctx.quadraticCurveTo(x + w, y + h, x + w - radius, y + h);
    ctx.lineTo(x + radius, y + h);
    ctx.quadraticCurveTo(x, y + h, x, y + h - radius);
    ctx.lineTo(x, y + radius);
    ctx.quadraticCurveTo(x, y, x + radius, y);
    ctx.closePath();
  };

  // 调整画布尺寸
  const resize = () => {
    const canvas = canvasRef.current;
    const panel = panelRef.current;
    if (!canvas || !panel) return;

    const ctx = canvas.getContext("2d");
    if (!ctx) return;
    const dpr = window.devicePixelRatio || 1;
    const w = panel.clientWidth;
    const h = panel.clientHeight;

    canvas.width = w * dpr;
    canvas.height = h * dpr;
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
  };

  // 主绘制函数
  const draw = (ts: any) => {
    const canvas = canvasRef.current;
    const panel = panelRef.current;
    if (!canvas || !panel) return;

    const ctx = canvas.getContext("2d");
    if (!ctx) return;
    const w = panel.clientWidth;
    const h = panel.clientHeight;
    const padX = 12;
    const barGap = 4;
    const barWidth = 2;
    const usableW = w - padX * 2;
    const count = Math.floor(usableW / (barWidth + barGap));

    // 获取音量级别
    const level = getLeftLevelFromUser() || 0;

    // 每50ms添加新柱子
    if (ts - lastBarTimeRef.current >= LEFT_NEW_BAR_MS) {
      const newBar = clamp(Math.pow(level, 0.85));
      barsRef.current.push(newBar);
      if (barsRef.current.length > count) barsRef.current.shift();
      lastBarTimeRef.current = ts;
    }

    // 清除背景
    ctx.clearRect(0, 0, w, h);
    ctx.fillStyle = "rgba(205,208,220,0.15)";
    ctx.fillRect(0, 0, w, h);

    // 绘制中线
    const midX = Math.floor(w / 2) + 0.5;
    ctx.beginPath();
    ctx.moveTo(midX, 0);
    ctx.lineTo(midX, h);
    ctx.lineWidth = 2;
    ctx.strokeStyle = "#615CED";
    ctx.stroke();

    // 绘制左侧动态柱
    let x = midX - (barWidth + barGap);
    for (let i = barsRef.current.length - 1; i >= 0; i--) {
      const v = barsRef.current[i];
      const barH = Math.max(LEFT_MIN_H, v * LEFT_MAX_H);
      const top = (h - barH) / 2;
      if (x - barWidth < padX) break;

      ctx.fillStyle = "rgba(55,65,81,0.68)";
      roundRect(ctx, x - barWidth, top, barWidth, barH, barWidth);
      ctx.fill();
      x -= barWidth + barGap;
    }

    // 绘制右侧静态柱
    x = midX + barGap;
    for (; x < w - padX; x += barWidth + barGap) {
      const barH = 4;
      const top = (h - barH) / 2;
      ctx.fillStyle = "rgba(55,65,81,0.25)";
      roundRect(ctx, x, top, barWidth, barH, barWidth);
      ctx.fill();
    }

    animationIdRef.current = requestAnimationFrame(draw);
  };

  useEffect(() => {
    resize();

    const resizeObserver = new ResizeObserver(resize);
    if (panelRef.current) {
      resizeObserver.observe(panelRef.current);
    }

    animationIdRef.current = requestAnimationFrame(draw);

    return () => {
      if (animationIdRef.current) {
        cancelAnimationFrame(animationIdRef.current);
      }
      resizeObserver.disconnect();
    };
  }, []);

  const onVolume = (data: VolumeData) => {
    const { volume } = data;

    volumeRef.current = volume / 10;
  };
  // 获取配置
  const microphoneOptions: MicrophoneOptions = {
    ...microphoneConfigs.highSensitivity,
    onVolumeChange: onVolume,
  };
  const { startListening, stopListening } = useMicrophone(microphoneOptions);

  useEffect(() => {
    // startListening();
    if (isStarting) {
      // 恢复时重新启动动画循环
      if (!animationIdRef.current) {
        animationIdRef.current = requestAnimationFrame(draw);
      }
      startListening();
    } else {
      // 暂停时取消动画循环
      if (animationIdRef.current) {
        cancelAnimationFrame(animationIdRef.current);
        animationIdRef.current = null;
      }
      stopListening();
    }
  }, [isStarting]);

  return (
    <Panel ref={panelRef}>
      <canvas ref={canvasRef} className="canvas" />
      <div className="fadeLeft" />
      <div className="centerCap" />
    </Panel>
  );
};

export default MicrophoneAnimation;
