/**
 * 我的音色页面 — V21 Design System
 *
 * 展示克隆音色列表，卡片网格布局
 * 支持试听、使用、编辑名称、删除操作
 */
import React, { useState, useCallback } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { Button, Tooltip } from "@/components/ui";
import { Popconfirm } from "antd";
import {
  EditOutlined,
  DeleteOutlined,
  AudioOutlined,
  SoundOutlined,
  CalendarOutlined,
  CheckCircleOutlined,
  CloseCircleOutlined,
} from "@ant-design/icons";
import PageHead from "@/components/layout/PageHead";
import CloneVoiceModal from "@/components/modals/CloneVoiceModal";
import {
  getVoiceClones,
  deleteVoiceClone,
  updateVoiceClone,
  formatDuration,
  type VoiceClone as VoiceCloneType,
} from "@/api/voiceClone";
import "./voice-clone.css";

/* ── 状态配置 ─────────────────────────────────────────── */

const STATUS_CONFIG: Record<
  VoiceCloneType["status"],
  { label: string; className: string }
> = {
  ready: { label: "就绪", className: "vc-status-pill--ready" },
  processing: { label: "克隆中", className: "vc-status-pill--processing" },
  failed: { label: "失败", className: "vc-status-pill--failed" },
};

/* ── Toast 系统 ─────────────────────────────────────────── */

interface Toast {
  id: number;
  message: string;
  type: "success" | "error";
}

let toastId = 0;

/* ── 音色卡片组件 ───────────────────────────────────────── */

interface VoiceCloneCardProps {
  voice: VoiceCloneType;
  onPlay: (voice: VoiceCloneType) => void;
  onUse: (voice: VoiceCloneType) => void;
  onEdit: (voice: VoiceCloneType) => void;
  onDelete: (voice: VoiceCloneType) => void;
}

const VoiceCloneCard: React.FC<VoiceCloneCardProps> = ({
  voice,
  onPlay,
  onUse,
  onEdit,
  onDelete,
}) => {
  const statusCfg = STATUS_CONFIG[voice.status];
  const isProcessing = voice.status === "processing";
  const createdDate = new Date(voice.created_at).toLocaleDateString("zh-CN");

  return (
    <div className="vc-card">
      {/* 右上角操作 */}
      <div className="vc-card-actions">
        <Tooltip title="编辑名称">
          <button
            type="button"
            className="vc-card-action-btn"
            onClick={() => onEdit(voice)}
          >
            <EditOutlined />
          </button>
        </Tooltip>
        <Tooltip title="删除">
          <Popconfirm
            title={`确定删除音色「${voice.name}」吗？`}
            onConfirm={() => onDelete(voice)}
            okText="删除"
            cancelText="取消"
          >
            <button
              type="button"
              className="vc-card-action-btn vc-card-action-btn--danger"
            >
              <DeleteOutlined />
            </button>
          </Popconfirm>
        </Tooltip>
      </div>

      {/* 头部：头像 + 名称 + 状态 */}
      <div className="vc-card-header">
        <div
          className={`vc-card-avatar${isProcessing ? " vc-card-avatar--processing" : ""}`}
        >
          <AudioOutlined style={{ fontSize: 22 }} />
        </div>
        <div className="vc-card-info">
          <h4 className="vc-card-name">{voice.name}</h4>
          <span className={`vc-status-pill ${statusCfg.className}`}>
            <span className="vc-status-dot" />
            {statusCfg.label}
          </span>
        </div>
      </div>

      {/* 元信息 */}
      <div className="vc-card-meta">
        <div className="vc-card-meta-row">
          <span className="vc-card-meta-icon">
            <SoundOutlined />
          </span>
          <span>时长：{formatDuration(voice.duration_seconds)}</span>
        </div>
        <div className="vc-card-meta-row">
          <span className="vc-card-meta-icon">
            <CalendarOutlined />
          </span>
          <span>创建于：{createdDate}</span>
        </div>
      </div>

      {/* 操作区 */}
      <div className="vc-card-footer">
        <Button
          buttonType="ghost"
          buttonSize="sm"
          disabled={isProcessing}
          onClick={() => onPlay(voice)}
        >
          ▶ 试听
        </Button>
        <Button
          buttonType="primary"
          buttonSize="sm"
          disabled={isProcessing}
          onClick={() => onUse(voice)}
        >
          使用此音色
        </Button>
      </div>
    </div>
  );
};

/* ── 主页面 ─────────────────────────────────────────────── */

const VoiceClone: React.FC = () => {
  const queryClient = useQueryClient();
  const [toasts, setToasts] = useState<Toast[]>([]);
  const [editingVoice, setEditingVoice] = useState<VoiceCloneType | null>(null);
  const [editName, setEditName] = useState("");
  const [cloneModalOpen, setCloneModalOpen] = useState(false);

  /** 显示 toast */
  const showToast = useCallback((message: string, type: Toast["type"]) => {
    const id = ++toastId;
    setToasts((prev) => [...prev, { id, message, type }]);
    setTimeout(() => {
      setToasts((prev) => prev.filter((t) => t.id !== id));
    }, 3000);
  }, []);

  /** 查询克隆音色列表 */
  const { data: voices = [], isLoading } = useQuery({
    queryKey: ["voiceClones"],
    queryFn: () => getVoiceClones(),
  });

  /** 删除 mutation */
  const deleteMutation = useMutation({
    mutationFn: deleteVoiceClone,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["voiceClones"] });
      showToast("音色已删除", "success");
    },
    onError: () => {
      showToast("删除失败", "error");
    },
  });

  /** 编辑 mutation */
  const updateMutation = useMutation({
    mutationFn: ({ id, name }: { id: string; name: string }) =>
      updateVoiceClone(id, { name }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["voiceClones"] });
      setEditingVoice(null);
      showToast("名称已更新", "success");
    },
    onError: () => {
      showToast("更新失败", "error");
    },
  });

  /** 克隆新音色 — 打开弹窗 */
  const handleCloneNew = () => {
    setCloneModalOpen(true);
  };

  /** 试听 */
  const handlePlay = (voice: VoiceCloneType) => {
    if (voice.sample_url) {
      const audio = new Audio(voice.sample_url);
      audio.play().catch(() => {
        showToast("播放失败", "error");
      });
    } else {
      showToast("暂无试听音频", "error");
    }
  };

  /** 使用音色 — 跳转到生成页面 */
  const handleUse = (_voice: VoiceCloneType) => {
    showToast("已选择音色，跳转到生成页面", "success");
  };

  /** 打开编辑弹窗 */
  const handleEdit = (voice: VoiceCloneType) => {
    setEditingVoice(voice);
    setEditName(voice.name);
  };

  /** 确认编辑 */
  const handleEditConfirm = () => {
    if (!editingVoice || !editName.trim()) return;
    updateMutation.mutate({ id: editingVoice.id, name: editName.trim() });
  };

  /** 删除确认 — 使用 Popconfirm */
  const handleDelete = (voice: VoiceCloneType) => {
    deleteMutation.mutate(voice.id);
  };

  return (
    <div className="vc-page">
      <PageHead
        title="我的音色库"
        description="克隆和管理你的专属音色，用AI生成个性化配音"
        actions={
          <Button buttonType="primary" onClick={handleCloneNew}>
            克隆新音色
          </Button>
        }
      />

      {/* 加载状态 — 骨架屏 */}
      {isLoading && (
        <div className="vc-grid">
          {[1, 2, 3].map((i) => (
            <div key={i} className="vc-card">
              <div className="vc-card-header">
                <div className="vc-skeleton-avatar" />
                <div style={{ flex: 1 }}>
                  <div className="vc-skeleton-line vc-skeleton-line--title" />
                  <div className="vc-skeleton-line vc-skeleton-line--short" />
                </div>
              </div>
              <div className="vc-skeleton-line" />
              <div className="vc-skeleton-line vc-skeleton-line--short" />
              <div className="vc-skeleton-line vc-skeleton-line--footer" />
            </div>
          ))}
        </div>
      )}

      {/* 卡片网格 */}
      {!isLoading && voices.length > 0 && (
        <div className="vc-grid">
          {voices.map((voice) => (
            <VoiceCloneCard
              key={voice.id}
              voice={voice}
              onPlay={handlePlay}
              onUse={handleUse}
              onEdit={handleEdit}
              onDelete={handleDelete}
            />
          ))}
        </div>
      )}

      {/* 空状态 */}
      {!isLoading && voices.length === 0 && (
        <div className="vc-empty">
          <div className="vc-empty-icon">
            <AudioOutlined style={{ fontSize: 48 }} />
          </div>
          <h3 className="vc-empty-title">还没有克隆音色</h3>
          <p className="vc-empty-desc">上传你的声音，AI将克隆你的专属音色</p>
          <Button buttonType="primary" onClick={handleCloneNew}>
            立即克隆
          </Button>
        </div>
      )}

      {/* Toast 提示 */}
      {toasts.length > 0 && (
        <div className="vc-toast-container">
          {toasts.map((t) => (
            <div key={t.id} className={`vc-toast vc-toast--${t.type}`}>
              {t.type === "success" ? (
                <CheckCircleOutlined />
              ) : (
                <CloseCircleOutlined />
              )}{" "}
              {t.message}
            </div>
          ))}
        </div>
      )}

      {/* 编辑弹窗 */}
      {editingVoice && (
        <div className="vc-edit-overlay" onClick={() => setEditingVoice(null)}>
          <div className="vc-edit-dialog" onClick={(e) => e.stopPropagation()}>
            <h3 className="vc-edit-title">编辑音色名称</h3>
            <input
              type="text"
              className="vc-edit-input"
              value={editName}
              onChange={(e) => setEditName(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === "Enter") handleEditConfirm();
                if (e.key === "Escape") setEditingVoice(null);
              }}
              autoFocus
              placeholder="输入音色名称"
            />
            <div className="vc-edit-buttons">
              <Button buttonType="ghost" onClick={() => setEditingVoice(null)}>
                取消
              </Button>
              <Button
                buttonType="primary"
                onClick={handleEditConfirm}
                disabled={updateMutation.isPending}
              >
                {updateMutation.isPending ? "保存中..." : "保存"}
              </Button>
            </div>
          </div>
        </div>
      )}

      {/* 克隆音色弹窗 */}
      <CloneVoiceModal
        open={cloneModalOpen}
        onClose={() => setCloneModalOpen(false)}
        onSuccess={() => {
          queryClient.invalidateQueries({ queryKey: ["voiceClones"] });
          showToast("音色克隆已提交", "success");
        }}
      />
    </div>
  );
};

export default VoiceClone;
