"use client";

import React, { useState, useRef, useEffect } from "react";
import {
  Mic,
  MicOff,
  Upload,
  Play,
  Pause,
  Trash2,
  X,
  Volume2,
} from "lucide-react";
import { Tooltip, Upload as AntdUpload, message } from "antd";
import { InboxOutlined } from "@ant-design/icons";
import WaveSurfer from "wavesurfer.js";

import {
  getAudioDuration,
  useUploadFile,
} from "../../app/service/domain/service";

// 自定义样式
const audioRecorderStyles = `
  .slider {
    -webkit-appearance: none;
    appearance: none;
    background: transparent;
    cursor: pointer;
  }

  .slider::-webkit-slider-track {
    background: rgba(255, 255, 255, 0.2);
    height: 4px;
    border-radius: 2px;
  }

  .slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    background: #3b82f6;
    height: 12px;
    width: 12px;
    border-radius: 50%;
    cursor: pointer;
    transition: all 0.2s ease;
  }

  .slider::-webkit-slider-thumb:hover {
    background: #2563eb;
    transform: scale(1.1);
  }

  .slider::-moz-range-track {
    background: rgba(255, 255, 255, 0.2);
    height: 4px;
    border-radius: 2px;
    border: none;
  }

  .slider::-moz-range-thumb {
    background: #3b82f6;
    height: 12px;
    width: 12px;
    border-radius: 50%;
    cursor: pointer;
    border: none;
    transition: all 0.2s ease;
  }

  .slider::-moz-range-thumb:hover {
    background: #2563eb;
    transform: scale(1.1);
  }
`;

interface AudioRecorderProps {
  /** 当前音频URL */
  audioUrl?: string;
  /** 录制完成回调 */
  onAudioRecorded: (audioBlob: Blob, audioUrl: string) => void;
  /** 删除音频回调 */
  onAudioDeleted: () => void;
  /** 组件标题 */
  title?: string;
  /** 是否显示关闭按钮 */
  showCloseButton?: boolean;
  /** 关闭回调 */
  onClose?: () => void;
}

/**
 * 音频录制组件，支持录制、上传和播放功能
 */
export function AudioRecorder({
  audioUrl,
  onAudioRecorded,
  onAudioDeleted,
  showCloseButton = false,
  onClose,
}: AudioRecorderProps) {
  const [mode, setMode] = useState<"upload" | "record">("upload"); // 当前模式：上传或录制
  const [isRecording, setIsRecording] = useState(false);
  const [isPlaying, setIsPlaying] = useState(false);
  const [volume, setVolume] = useState(1);
  const [isMuted, setIsMuted] = useState(false);
  const [recordingTime, setRecordingTime] = useState(0); // 录制时长（秒）
  const [isUploadingRecording, setIsUploadingRecording] = useState(false); // 录制音频上传状态
  const { uploadFile, isUploading } = useUploadFile();

  const mediaRecorderRef = useRef<MediaRecorder | null>(null);
  const chunksRef = useRef<Blob[]>([]);
  const recordingTimerRef = useRef<NodeJS.Timeout | null>(null); // 录制计时器引用
  const actualRecordingTimeRef = useRef<number>(0); // 实际录制时长引用，用于准确获取时长

  // 清理计时器
  useEffect(() => {
    return () => {
      if (recordingTimerRef.current) {
        clearInterval(recordingTimerRef.current);
      }
    };
  }, []);

  // 开始录制
  const startRecording = async () => {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });

      // 检查支持的音频格式，优先使用 webm
      const mimeType = MediaRecorder.isTypeSupported("audio/webm")
        ? "audio/webm"
        : "audio/mp4";

      const mediaRecorder = new MediaRecorder(stream, { mimeType });
      mediaRecorderRef.current = mediaRecorder;
      chunksRef.current = [];

      mediaRecorder.ondataavailable = (event) => {
        if (event.data.size > 0) {
          chunksRef.current.push(event.data);
        }
      };

      mediaRecorder.onstop = async () => {
        const audioBlob = new Blob(chunksRef.current, { type: mimeType });

        // 先停止计时器，然后获取最终时长
        if (recordingTimerRef.current) {
          clearInterval(recordingTimerRef.current);
          recordingTimerRef.current = null;
        }

        // 使用引用值获取准确的录制时长
        const duration = actualRecordingTimeRef.current;
        console.log("录制时长:", duration, "秒");

        // 无论时长是否符合要求，都要释放麦克风权限
        stream.getTracks().forEach((track) => track.stop());

        if (duration > 20 || duration < 10) {
          message.warning(
            "Please keep your audio between 10 and 20 seconds to help us better learn your voice."
          );
          return;
        }

        try {
          // 将 Blob 转换为 File 对象，以便上传
          const audioFile = new File(
            [audioBlob],
            `recording_${Date.now()}.webm`,
            { type: mimeType }
          );

          // 设置上传状态
          setIsUploadingRecording(true);

          // 使用 uploadFile 上传到服务器
          console.log("开始上传录制的音频文件...");
          const uploadedUrl = await uploadFile(audioFile);
          console.log("音频上传成功，服务器URL:", uploadedUrl);

          // 使用服务器返回的真实URL地址
          onAudioRecorded(audioBlob, uploadedUrl);
        } catch (error) {
          console.error("音频上传失败:", error);
          message.error("音频上传失败，请重试");
          return;
        } finally {
          setIsUploadingRecording(false);
        }

        // 重置计时器状态
        setRecordingTime(0);
        actualRecordingTimeRef.current = 0; // 重置引用值
        setIsRecording(false);
      };

      mediaRecorder.start();
      setIsRecording(true);
      setRecordingTime(0); // 重置计时器
      actualRecordingTimeRef.current = 0; // 重置引用值

      // 开始计时
      recordingTimerRef.current = setInterval(() => {
        setRecordingTime((prev) => prev + 1);
        actualRecordingTimeRef.current += 1; // 同时更新引用值
      }, 1000);
    } catch (error) {
      console.error("录制失败:", error);
    }
  };

  // 停止录制
  const stopRecording = () => {
    if (mediaRecorderRef.current && isRecording) {
      mediaRecorderRef.current.stop();
      setIsRecording(false);
      // 注意：计时器清理现在在 onstop 回调中处理
    }
  };

  // 播放/暂停控制
  const togglePlay = () => {
    setIsPlaying(!isPlaying);
  };

  // 音量调节
  const handleVolumeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const newVolume = parseFloat(e.target.value);
    setVolume(newVolume);
    if (isMuted && newVolume > 0) {
      setIsMuted(false);
    }
  };

  // 删除音频
  const handleDelete = () => {
    setIsPlaying(false);
    onAudioDeleted();
  };

  // 渲染上传/录制状态
  if (!audioUrl) {
    return (
      <>
        <style>{audioRecorderStyles}</style>
        <div className="relative bg-white/[0.05] border border-white/[0.1] rounded-lg p-4">
          {/* 头部 - 只显示关闭按钮 */}
          {showCloseButton && (
            <div className="flex justify-end mb-2">
              <button
                onClick={onClose}
                className="text-white/60 hover:text-white/80 transition-colors"
              >
                <X className="w-4 h-4" />
              </button>
            </div>
          )}

          {/* 主要内容区域 */}
          <div className="flex items-center justify-center min-h-[60px]">
            {mode === "upload" ? (
              // 上传模式
              <div className="text-center w-full flex flex-col justify-center  h-32 ">
                <Tooltip
                  title="Please clearly read the story description above and record a 15-second audio file for upload"
                  placement="top"
                  classNames={{ root: "max-w-xs" }}
                >
                  <div>
                    <AntdUpload.Dragger
                      accept="audio/*"
                      beforeUpload={async (file) => {
                        console.log("beforeUpload 被调用:", file);
                        // 移除 return false，让文件能够正常进入 customRequest
                        const duration = await getAudioDuration(file);
                        console.log("duration", duration);
                        if (duration > 20 || duration < 10) {
                          message.warning(
                            "Please keep your audio between 10 and 20 seconds to help us better learn your voice."
                          );
                          return false;
                        }
                        return true;
                      }}
                      customRequest={async ({ file, onSuccess, onError }) => {
                        console.log("customRequest 被调用，文件:", file);
                        try {
                          const fileObj = file as File;
                          console.log(
                            "开始上传文件:",
                            fileObj.name,
                            fileObj.type,
                            fileObj.size
                          );

                          if (fileObj && fileObj.type.startsWith("audio/")) {
                            // 使用 hook 上传文件到七牛云
                            console.log("调用 uploadFile hook...");
                            const uploadedUrl = await uploadFile(fileObj);
                            console.log("上传成功，URL:", uploadedUrl);

                            // 上传成功后，调用回调函数
                            onAudioRecorded(fileObj, uploadedUrl);
                            onSuccess?.(uploadedUrl);
                          } else {
                            console.log("文件类型不是音频:", fileObj?.type);
                            const error = new Error("文件类型不是音频文件");
                            onError?.(error);
                          }
                        } catch (error) {
                          console.error("上传失败:", error);
                          // 上传失败时直接报告错误，不使用本地文件作为备选
                          onError?.(error as Error);
                        }
                      }}
                      showUploadList={false}
                      className="bg-transparent border-dashed border-white/20 hover:border-white/40"
                      disabled={isUploading}
                      onChange={(info) => {
                        console.log("Upload onChange 事件:", info);
                      }}
                      onDrop={(e) => {
                        console.log("文件拖拽事件:", e);
                      }}
                    >
                      <div className="text-2xl text-white/40 mb-2">
                        <InboxOutlined />
                      </div>
                      <div className="text-xs text-white/60">
                        {isUploading
                          ? "Uploading..."
                          : "Drag audio file here or click to upload"}
                      </div>
                    </AntdUpload.Dragger>
                  </div>
                </Tooltip>
              </div>
            ) : (
              // 录制模式
              <div className="text-center w-full flex flex-col justify-center h-32">
                {isRecording ? (
                  // 录制中状态
                  <div className="space-y-3">
                    <div className="flex items-center justify-center gap-3">
                      <button
                        onClick={stopRecording}
                        className="flex items-center gap-1.5 px-3 py-1.5 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors text-sm"
                      >
                        <MicOff className="w-3 h-3" />
                        <span>Stop</span>
                      </button>
                      <div className="text-xs text-white/60">Recording...</div>
                    </div>

                    {/* 录制状态指示器和计时器 */}
                    <div className="w-full h-12 bg-white/[0.05] rounded-lg flex items-center justify-center">
                      <div className="flex items-center gap-3 text-white/60">
                        <div className="w-2 h-2 bg-red-500 rounded-full animate-pulse"></div>
                        <span className="text-xs">Recording...</span>
                        <span className="text-sm font-mono text-red-400">
                          {Math.floor(recordingTime / 60)
                            .toString()
                            .padStart(2, "0")}
                          :{(recordingTime % 60).toString().padStart(2, "0")}
                        </span>
                      </div>
                    </div>
                  </div>
                ) : isUploadingRecording ? (
                  // 录制音频上传中状态
                  <div className="text-center">
                    <div className="text-xs text-white/60 mb-3">
                      Uploading recorded audio...
                    </div>
                    <div className="flex items-center justify-center">
                      <div className="w-8 h-8 border-2 border-white/20 border-t-white/60 rounded-full animate-spin"></div>
                    </div>
                  </div>
                ) : (
                  // 录制准备状态
                  <div className="text-center">
                    <div className="text-xs text-white/60 mb-3">
                      Click to start recording
                    </div>
                    <Tooltip
                      title="Please clearly read the story description above and record a 15-second audio"
                      placement="top"
                      classNames={{ root: "max-w-xs" }}
                    >
                      <button
                        onClick={startRecording}
                        className="flex items-center justify-center w-12 h-12 bg-red-500 text-white rounded-full hover:bg-red-600 transition-all duration-200 shadow-lg hover:shadow-xl mx-auto"
                        data-alt="record-button"
                      >
                        <Mic className="w-5 h-5" />
                      </button>
                    </Tooltip>
                  </div>
                )}
              </div>
            )}
          </div>

          {/* 底部模式切换图标 */}
          <div className="flex justify-center gap-6 mt-3 pt-3 border-t border-white/[0.1]">
            <Tooltip title="Switch to upload mode" placement="top">
              <button
                onClick={() => setMode("upload")}
                className={`transition-colors ${
                  mode === "upload"
                    ? "text-[rgb(106,244,249)]"
                    : "text-white/40 hover:text-[rgb(106,244,249)]/60"
                }`}
              >
                <Upload className="w-5 h-5" />
              </button>
            </Tooltip>

            <Tooltip title="Switch to recording mode" placement="top">
              <button
                onClick={() => setMode("record")}
                className={`transition-colors ${
                  mode === "record"
                    ? "text-[rgb(199,59,255)]"
                    : "text-white/40 hover:text-[rgb(199,59,255)]/60"
                }`}
              >
                <Mic className="w-5 h-5" />
              </button>
            </Tooltip>
          </div>
        </div>
      </>
    );
  }

  // 渲染播放状态
  return (
    <>
      <style>{audioRecorderStyles}</style>
      <div
        className="relative bg-white/[0.05] border border-white/[0.1] rounded-lg p-4 h-52 group"
        data-alt="audio-player-container"
      >
        {/* 大旋转的播放圆盘 */}
        <div className=" absolute z-1 right-6 top-[50%] translate-y-[-50%] scale-[1.4]">
          <div className="relative">
            {/* 外层边框 - 唱片边缘 */}
            <div
              className={`w-28 h-28 rounded-full border-4 border-gray-400/30 ${
                isPlaying ? "animate-spin" : ""
              }`}
              style={{
                animationDuration: "6s",
              }}
            ></div>

            {/* 唱片主体 - 纯黑色唱片面 */}
            <div
              className={`absolute inset-2 w-24 h-24 rounded-full bg-black shadow-[inset_0_2px_8px_rgba(0,0,0,0.8)] ${
                isPlaying ? "animate-spin" : ""
              }`}
              style={{ animationDuration: "6s" }}
            >
              {/* 唱片纹理 - 细密的同心圆 */}
              <div className="absolute inset-0 rounded-full bg-[radial-gradient(circle_at_center,transparent_0%,rgba(255,255,255,0.02)_1px,transparent_2px)] bg-[length:4px_4px]"></div>

              {/* 中心孔洞 - 透明圆环，显示背景色 */}
              <div className="absolute top-1/2 left-1/2 w-8 h-8 rounded-full -translate-x-1/2 -translate-y-1/2 bg-transparent border-2 border-white/20"></div>

              {/* MovieFlow 字母 - 环形文本效果 */}
              <div className="absolute inset-0">
                <svg
                  viewBox="0 0 96 96"
                  className="w-full h-full"
                  style={{
                    filter: "drop-shadow(0 0 8px rgba(106, 244, 249, 0.3))",
                  }}
                >
                  {/* 定义渐变 */}
                  <defs>
                    <linearGradient
                      id="movieFlowGradient"
                      x1="0%"
                      y1="0%"
                      x2="100%"
                      y2="0%"
                    >
                      <stop offset="30%" stopColor="rgb(106, 244, 249)" />
                      <stop offset="70%" stopColor="rgb(199, 59, 255)" />
                    </linearGradient>
                  </defs>

                  {/* 圆形路径 - 减小半径让文字更靠近中心 */}
                  <path
                    id="movieFlowCircle"
                    d="M 48,16 a 32,32 0 1,1 0,64 a 32,32 0 1,1 0,-64"
                    fill="none"
                    stroke="none"
                  />

                  {/* 环形文本 - 调整起始位置让文字更居中 */}
                  <text fontSize="12" fontWeight="bold" letterSpacing="1">
                    <textPath
                      href="#movieFlowCircle"
                      startOffset="25%"
                      textAnchor="middle"
                      fill="url(#movieFlowGradient)"
                    >
                      MovieFlow
                    </textPath>
                  </text>
                </svg>
              </div>
            </div>

            {/* 唱片光泽效果 */}
            <div
              className={`absolute inset-2 w-24 h-24 rounded-full bg-gradient-to-br from-transparent via-white/5 to-transparent ${
                isPlaying ? "animate-spin" : ""
              }`}
              style={{ animationDuration: "10s" }}
            ></div>
          </div>
        </div>

        {/* 头部 - 只显示操作按钮 */}
        <div className="relative z-10 flex justify-end gap-2 mb-3 opacity-0 group-hover:opacity-100 transition-opacity duration-200">
          <button
            onClick={handleDelete}
            className="text-white/60 hover:text-red-400 transition-colors"
            title="Delete audio"
            data-alt="delete-audio-button"
          >
            <Trash2 className="w-4 h-4" />
          </button>
          {showCloseButton && (
            <button
              onClick={onClose}
              className="text-white/60 hover:text-white/80 transition-colors"
              data-alt="close-audio-button"
            >
              <X className="w-4 h-4" />
            </button>
          )}
        </div>
        {/* 播放控制 */}
        <div className="relative z-10 flex items-center justify-center gap-4 mb-4 mt-12">
          <button
            onClick={togglePlay}
            className="flex items-center justify-center w-12 h-12 bg-gradient-to-br from-[rgb(106,244,249)] to-[rgb(199,59,255)] text-white rounded-xl shadow-[inset_0_1px_0_rgba(255,255,255,0.3),0_4px_12px_rgba(0,0,0,0.3)] hover:shadow-[inset_0_1px_0_rgba(255,255,255,0.4),0_6px_20px_rgba(106,244,249,0.4)] transition-all duration-300 hover:scale-105 active:scale-95"
          >
            {isPlaying ? (
              <Pause className="w-5 h-5 drop-shadow-sm" />
            ) : (
              <Play className="w-5 h-5 drop-shadow-sm ml-0.5" />
            )}
          </button>
          {/* WaveSurfer 波形图区域 */}
          <div className="h-16 flex-1 bg-white/[0.05] rounded-lg overflow-hidden">
            <WaveformPlayer
              audioUrl={audioUrl}
              isPlaying={isPlaying}
              onPlayStateChange={setIsPlaying}
              volume={volume}
              isMuted={isMuted}
            />
          </div>
        </div>

        {/* 音频设置 */}
        <div className="flex items-center justify-between px-2">
          <div className="flex items-center gap-6">
            {/* 音量控制 */}
            <div className="flex items-center gap-3">
              <div className="w-24 h-3 bg-white/[0.08] rounded-full overflow-hidden shadow-inner border border-white/[0.1] relative">
                <div
                  className="h-full bg-gradient-to-r from-[rgb(106,244,249)] to-[rgb(199,59,255)] rounded-full transition-all duration-300"
                  style={{ width: `${volume * 100}%` }}
                />
                {/* 可拖拽的音量滑块 */}
                <input
                  type="range"
                  min="0"
                  max="1"
                  step="0.01"
                  value={volume}
                  onChange={handleVolumeChange}
                  className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
                />
                {/* 视觉滑块指示器 */}
                <div
                  className="absolute top-1/2 -translate-y-1/2 w-4 h-4 bg-white rounded-full shadow-lg border-2 border-[rgb(199,59,255)] pointer-events-none transition-all duration-200"
                  style={{ left: `calc(${volume * 100}% - 8px)` }}
                />
              </div>
              {/* 音频图标 */}
              <div className="text-white/70 hover:text-white/90 transition-colors">
                <Volume2 className="w-5 h-5" />
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

/**
 * 音频波形播放器组件的属性接口
 */
interface WaveformPlayerProps {
  /** 音频文件的URL地址 */
  audioUrl: string;
  /** 当前播放状态，true表示正在播放，false表示暂停或停止 */
  isPlaying: boolean;
  /** 播放状态变化时的回调函数，用于同步外部播放状态 */
  onPlayStateChange: (isPlaying: boolean) => void;
  /** 音量大小，范围0-1，默认为1（最大音量） */
  volume?: number;
  /** 是否静音，true表示静音，false表示有声音，默认为false */
  isMuted?: boolean;
}

/**
 * 音频波形播放器组件
 *
 * 使用 WaveSurfer.js 库创建可视化的音频波形播放器，支持播放控制、音量调节和静音功能。
 * 组件会自动同步外部传入的播放状态，确保播放控制的一致性。
 *
 * @param {string} audioUrl - 音频文件的URL地址
 * @param {boolean} isPlaying - 当前播放状态
 * @param {function} onPlayStateChange - 播放状态变化回调函数
 * @param {number} [volume=1] - 音量大小，范围0-1
 * @param {boolean} [isMuted=false] - 是否静音
 * @returns {JSX.Element} 渲染的波形播放器组件
 * ```
 */
function WaveformPlayer({
  audioUrl,
  isPlaying,
  onPlayStateChange,
  volume = 1,
  isMuted = false,
}: WaveformPlayerProps) {
  /** 容器DOM元素的引用，用于挂载WaveSurfer实例 */
  const containerRef = useRef<HTMLDivElement | null>(null);
  /** WaveSurfer实例的引用，用于控制音频播放 */
  const wavesurferRef = useRef<WaveSurfer | null>(null);

  /**
   * 初始化WaveSurfer实例
   * 当audioUrl变化时重新创建实例
   */
  useEffect(() => {
    if (!containerRef.current || !audioUrl) return;

    // 创建Canvas渐变
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    if (!ctx) return;

    const gradient = ctx.createLinearGradient(0, 0, 0, 64); // 64是波形高度
    gradient.addColorStop(0, "rgb(106, 244, 249)"); // 顶部：青色
    gradient.addColorStop(0.5, "rgb(152, 151, 254)"); // 中间：蓝紫色
    gradient.addColorStop(1, "rgb(199, 59, 255)"); // 底部：紫色

    // 创建WaveSurfer实例并配置样式
    const ws = WaveSurfer.create({
      container: containerRef.current,
      waveColor: gradient, // 使用渐变作为波形颜色
      progressColor: "rgb(152, 151, 254)", // 播放进度颜色 - 半透明白色，更优雅
      cursorColor: "rgb(152, 151, 254)", // 播放光标颜色 - 紫色
      height: 64, // 波形高度
      barWidth: 2, // 波形条宽度
      barGap: 1, // 波形条间距
      normalize: true, // 自动标准化波形
      url: audioUrl, // 音频文件URL
    });

    // 监听播放状态变化事件，同步到外部状态
    ws.on("play", () => onPlayStateChange(true)); // 开始播放
    ws.on("pause", () => onPlayStateChange(false)); // 暂停播放
    ws.on("finish", () => onPlayStateChange(false)); // 播放结束

    wavesurferRef.current = ws;

    // 组件卸载时销毁WaveSurfer实例，释放资源
    return () => {
      ws.destroy();
    };
  }, [audioUrl, onPlayStateChange]);

  /**
   * 同步外部播放状态和音量设置
   * 当isPlaying、volume或isMuted变化时，同步到WaveSurfer实例
   */
  useEffect(() => {
    if (!wavesurferRef.current) return;

    // 同步播放状态：如果外部状态为播放但WaveSurfer未播放，则开始播放
    if (isPlaying && !wavesurferRef.current.isPlaying()) {
      wavesurferRef.current.play();
    }
    // 如果外部状态为暂停但WaveSurfer正在播放，则暂停播放
    else if (!isPlaying && wavesurferRef.current.isPlaying()) {
      wavesurferRef.current.pause();
    }

    // 设置音量：静音时设为0，否则使用传入的音量值
    const currentVolume = isMuted ? 0 : volume;
    wavesurferRef.current.setVolume(currentVolume);
  }, [isPlaying, volume, isMuted]);

  return (
    <div className="w-full h-full">
      <div ref={containerRef} className="w-full h-full" />
    </div>
  );
}
