/**
 * CloneVoiceModal — 音色克隆弹窗
 *
 * 三步骤状态：input → uploading → success
 * 支持上传音频文件或直接录制（mock，无真实录音）
 *
 * V21 Design System — 零 antd 直接导入
 */
import React, { useState, useCallback, useRef } from "react";
import { Modal, Button } from "@/components/ui";
import { createVoiceClone, toVoiceClone } from "@/api/voiceClone";
import type { VoiceClone } from "@/api/voiceClone";
import { uploadAsset } from "@/api/assets";
import "./clone-voice-modal.css";

/* ── 类型定义 ───────────────────────────────────────────── */

type ModalStep = "input" | "uploading" | "success";

export interface CloneVoiceModalProps {
  /** 弹窗是否可见 */
  open: boolean;
  /** 关闭弹窗回调 */
  onClose: () => void;
  /** 克隆成功回调（返回新创建的音色） */
  onSuccess?: (voice: VoiceClone) => void;
}

/* ── 默认音色名称计数器 ─────────────────────────────────── */

let cloneCounter = 1;

const getNextDefaultName = (): string => {
  const name = `我的声音 ${cloneCounter}`;
  cloneCounter += 1;
  return name;
};

/* ── 组件 ───────────────────────────────────────────────── */

const CloneVoiceModal: React.FC<CloneVoiceModalProps> = ({
  open,
  onClose,
  onSuccess,
}) => {
  const [step, setStep] = useState<ModalStep>("input");
  const [voiceName, setVoiceName] = useState("");
  const [isRecording, setIsRecording] = useState(false);
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [dragActive, setDragActive] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  /** 重置弹窗状态 */
  const resetState = useCallback(() => {
    setStep("input");
    setVoiceName("");
    setSelectedFile(null);
    setIsRecording(false);
    setDragActive(false);
  }, []);

  /** 关闭弹窗 */
  const handleClose = useCallback(() => {
    resetState();
    onClose();
  }, [resetState, onClose]);

  /** 上传区域点击 */
  const handleUploadClick = () => {
    fileInputRef.current?.click();
  };

  /** 文件选择 */
  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
      setSelectedFile(file);
      // 清除之前的录制状态
      setIsRecording(false);
    }
    // 清空 input 以允许重复选择同一文件
    e.target.value = "";
  };

  /** 拖拽事件 */
  const handleDrag = (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    if (e.type === "dragenter" || e.type === "dragover") {
      setDragActive(true);
    } else if (e.type === "dragleave") {
      setDragActive(false);
    }
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setDragActive(false);
    const file = e.dataTransfer.files?.[0];
    if (file) {
      const ext = file.name.split(".").pop()?.toLowerCase();
      if (ext === "mp3" || ext === "wav") {
        setSelectedFile(file);
        setIsRecording(false);
      }
    }
  };

  /** 录制按钮（mock） */
  const handleRecord = () => {
    setIsRecording((prev) => !prev);
    if (!isRecording) {
      // 开始录制 — 清除已选文件
      setSelectedFile(null);
    }
  };

  /** 开始克隆 */
  const handleStartClone = async () => {
    const name = voiceName.trim() || getNextDefaultName();
    setStep("uploading");

    try {
      // 先上传音频文件获取真实 URL
      let audioUrl: string;
      if (selectedFile) {
        const formData = new FormData();
        formData.append("file", selectedFile);
        formData.append("kind", "voice");
        const uploadResult = await uploadAsset(formData);
        audioUrl = uploadResult.url;
      } else {
        // 录制功能暂未实现，提示用户上传
        setStep("input");
        return;
      }

      // 提交克隆请求
      const result = await createVoiceClone({
        name,
        audio_url: audioUrl,
      });

      setStep("success");

      // 2秒后自动关闭
      setTimeout(() => {
        onSuccess?.(toVoiceClone(result));
        handleClose();
      }, 2000);
    } catch {
      setStep("input");
    }
  };

  /** 弹窗打开时初始化默认名称 */
  const handleAfterOpenChange = (visible: boolean) => {
    if (visible) {
      setVoiceName(getNextDefaultName());
    }
  };

  const canStart = selectedFile || isRecording;

  return (
    <Modal
      open={open}
      onCancel={handleClose}
      title="🎤 克隆新音色"
      width={520}
      footer={null}
      destroyOnClose
      afterOpenChange={handleAfterOpenChange}
    >
      {/* ── 输入步骤 ──────────────────────────────────── */}
      {step === "input" && (
        <div className="cvm-body">
          {/* 音色名称 */}
          <div className="cvm-field">
            <label className="cvm-label">音色名称</label>
            <input
              type="text"
              className="cvm-input"
              value={voiceName}
              onChange={(e) => setVoiceName(e.target.value)}
              placeholder="输入音色名称"
            />
          </div>

          {/* 上传区域 */}
          <div className="cvm-field">
            <label className="cvm-label">上传音频</label>
            <div
              className={`cvm-upload-zone${dragActive ? " cvm-upload-zone--active" : ""}`}
              onClick={handleUploadClick}
              onDragEnter={handleDrag}
              onDragOver={handleDrag}
              onDragLeave={handleDrag}
              onDrop={handleDrop}
            >
              <div className="cvm-upload-icon">🎵</div>
              <p className="cvm-upload-title">
                {selectedFile ? selectedFile.name : "拖拽音频文件到此处"}
              </p>
              <p className="cvm-upload-hint">支持 MP3、WAV 格式</p>
              <input
                ref={fileInputRef}
                type="file"
                accept=".mp3,.wav,audio/mpeg,audio/wav"
                style={{ display: "none" }}
                onChange={handleFileChange}
              />
            </div>
          </div>

          {/* 或分隔 */}
          <div className="cvm-divider">
            <div className="cvm-divider-line" />
            <span className="cvm-divider-text">或</span>
            <div className="cvm-divider-line" />
          </div>

          {/* 录制区域 */}
          <div className="cvm-field">
            <label className="cvm-label">直接录制</label>
            <div className="cvm-record-area">
              <p className="cvm-record-hint">
                {isRecording
                  ? "录制中…再次点击停止"
                  : "点击按钮开始录制你的声音"}
              </p>
              <button
                type="button"
                className={`cvm-record-btn${isRecording ? " cvm-record-btn--recording" : ""}`}
                onClick={handleRecord}
              >
                🎙️
              </button>
            </div>
          </div>

          {/* 提示 */}
          <div className="cvm-tip">
            <span className="cvm-tip-icon">💡</span>
            <span>
              建议上传10秒~3分钟的清晰语音，环境安静、语速均匀效果最佳
            </span>
          </div>

          {/* 底部按钮 */}
          <div className="cvm-footer">
            <Button buttonType="ghost" onClick={handleClose}>
              取消
            </Button>
            <Button
              buttonType="primary"
              disabled={!canStart}
              onClick={handleStartClone}
            >
              🎤 开始克隆
            </Button>
          </div>
        </div>
      )}

      {/* ── 上传中步骤 ────────────────────────────────── */}
      {step === "uploading" && (
        <div className="cvm-uploading">
          <div className="cvm-uploading-spinner" />
          <p className="cvm-uploading-text">正在克隆你的音色…</p>
          <p className="cvm-uploading-sub">AI 正在分析你的声音特征，请稍候</p>
        </div>
      )}

      {/* ── 成功步骤 ──────────────────────────────────── */}
      {step === "success" && (
        <div className="cvm-success">
          <div className="cvm-success-icon">✅</div>
          <h3 className="cvm-success-title">克隆已提交</h3>
          <p className="cvm-success-desc">
            音色正在生成中，完成后将出现在列表中
          </p>
        </div>
      )}
    </Modal>
  );
};

export default CloneVoiceModal;
