import { useState, useEffect, useRef } from 'react';
import { useVirtualizer } from '@tanstack/react-virtual';
import { invoke } from '@tauri-apps/api/core';
import { openPath } from '@tauri-apps/plugin-opener';
import { save } from '@tauri-apps/plugin-dialog';
import { getLocalFileUrl } from '../../utils/fileUrl';
import { toast } from '../../store/uiStore';
import { useNavigation } from '../../contexts/NavigationContext';
import { switchProject } from '../../store/projectStore';
import { localProjectApi } from '../../api/modules/localStorage';
import type { ProjectMeta } from '../../types/project';
import ConfirmModal from '../../components/Modal/ConfirmModal';

import type { ApiResponse } from '../../api/types';
import './ContentManagement.css';

interface LocalProjectMeta {
  id: string;
  title: string;
  topic?: string;
  status: 'draft' | 'published';
  createdAt: number;
  updatedAt: number;
  coverPath?: string;
  finalVideoPath?: string;
}

interface ProductItem {
  filename: string;
  path: string;
  created_at: number;
  file_size: number;
  duration: number;
  poster_path?: string;
}

interface DraftItem {
  id: string;
  title: string;
  createdAt: number;
  topic?: string;
  updatedAt: number;
}

type TabType = 'products' | 'drafts';

const tabs = [
  { id: 'products' as TabType, label: '成片' },
  { id: 'drafts' as TabType, label: '草稿箱' },
];



function formatDateFriendly(timestamp: number): string {
  const date = new Date(timestamp);
  const now = new Date();
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  const target = new Date(date.getFullYear(), date.getMonth(), date.getDate());
  const diffDays = Math.round((today.getTime() - target.getTime()) / (1000 * 60 * 60 * 24));
  if (diffDays === 0) {return '今天';}
  if (diffDays === 1) {return '昨天';}
  if (diffDays < 7) {return `${diffDays} 天前`;}
  return date.toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit' });
}

function formatFileSize(bytes: number): string {
  if (bytes < 1024) {return `${bytes} B`;}
  if (bytes < 1024 * 1024) {return `${(bytes / 1024).toFixed(1)} KB`;}
  if (bytes < 1024 * 1024 * 1024) {return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;}
  return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
}

function formatDuration(seconds: number): string {
  if (seconds <= 0) {return '';}
  const mins = Math.floor(seconds / 60);
  const secs = Math.floor(seconds % 60);
  if (mins > 0) {
    return `${mins}分${secs}秒`;
  }
  return `${secs}秒`;
}

function getBaseName(filename: string): string {
  const lastDot = filename.lastIndexOf('.');
  return lastDot > 0 ? filename.slice(0, lastDot) : filename;
}

function getExtension(filename: string): string {
  const lastDot = filename.lastIndexOf('.');
  return lastDot > 0 ? filename.slice(lastDot) : '';
}

function ProductCard({ product, onDelete, onRename }: {
  product: ProductItem;
  onDelete: (product: ProductItem) => void;
  onRename: (product: ProductItem, newName: string) => void;
}) {
  const videoRef = useRef<HTMLVideoElement>(null);
  const [isPlaying, setIsPlaying] = useState(false);
  const [isRenaming, setIsRenaming] = useState(false);
  const [editName, setEditName] = useState(getBaseName(product.filename));
  const [coverUrl, setCoverUrl] = useState('');
  const [isCoverLoading, setIsCoverLoading] = useState(false);
  const [videoUrl, setVideoUrl] = useState('');

  // 成品视频直接读取原文件，不经过转码缓存（成品已是 H.264 + yuv420p 标准格式）
  useEffect(() => {
    let canceled = false;
    getLocalFileUrl(product.path)
      .then(url => {
        if (!canceled) {setVideoUrl(url);}
      })
      .catch(err => {
        console.error('[ProductCard] 加载视频失败:', err);
      });
    return () => { canceled = true; };
  }, [product.path]);

  useEffect(() => {
    if (!product.poster_path) {
      setCoverUrl('');
      setIsCoverLoading(false);
      return;
    }
    let canceled = false;
    async function load() {
      setIsCoverLoading(true);
      try {
        const url = await getLocalFileUrl(product.poster_path!);
        if (canceled) {return;}
        setCoverUrl(url);
      } catch {
        if (!canceled) {setCoverUrl('');}
      } finally {
        if (!canceled) {setIsCoverLoading(false);}
      }
    }
    load();
    return () => {
      canceled = true;
    };
  }, [product.poster_path]);

  useEffect(() => {
    const video = videoRef.current;
    if (!video) {return;}
    const handlePlay = () => setIsPlaying(true);
    const handlePause = () => setIsPlaying(false);
    const handleEnded = () => setIsPlaying(false);
    video.addEventListener('play', handlePlay);
    video.addEventListener('pause', handlePause);
    video.addEventListener('ended', handleEnded);
    return () => {
      video.removeEventListener('play', handlePlay);
      video.removeEventListener('pause', handlePause);
      video.removeEventListener('ended', handleEnded);
    };
  }, [videoUrl]);

  const togglePlay = (e: React.MouseEvent) => {
    e.stopPropagation();
    const video = videoRef.current;
    if (!video) {return;}
    if (video.paused) { video.play(); setIsPlaying(true); }
    else { video.pause(); setIsPlaying(false); }
  };

  const handleOpen = () => openPath(product.path);

  const handleExport = async (e: React.MouseEvent) => {
    e.stopPropagation();
    try {
      const filename = product.path.split(/[\\/]/).pop() || 'video.mp4';
      const targetPath = await save({
        defaultPath: filename,
        filters: [{ name: '视频', extensions: ['mp4'] }],
      });
      if (!targetPath) {return;}
      const res = await invoke<{ code: number; data?: string; message: string }>('export_product', {
        sourcePath: product.path,
        targetPath,
      });
      if (res.code === 200) {
        toast.success('导出成功');
      } else {
        toast.error(res.message || '导出失败');
      }
    } catch {
      toast.error('导出失败');
    }
  };

  const startRename = (e: React.MouseEvent) => {
    e.stopPropagation();
    setIsRenaming(true);
    setEditName(getBaseName(product.filename));
  };

  const confirmRename = () => {
    const base = editName.trim();
    if (!base) {return;}
    const fullName = base + getExtension(product.filename);
    if (fullName === product.filename) { setIsRenaming(false); return; }
    onRename(product, fullName);
    setIsRenaming(false);
  };

  const cancelRename = () => {
    setIsRenaming(false);
    setEditName(getBaseName(product.filename));
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter') {confirmRename();}
    if (e.key === 'Escape') {cancelRename();}
  };

  return (
    <div className={`works-card ${isPlaying ? 'playing' : ''}`} onClick={handleOpen}>
      <div className="works-card-cover">
        {videoUrl ? (
          <>
            {isCoverLoading && <div className="works-card-loading"><div className="works-card-spinner" /></div>}
            {coverUrl && !isPlaying && <img src={coverUrl} alt="" className="works-card-poster" />}
            <video ref={videoRef} src={videoUrl} className="works-card-video" preload="metadata" playsInline />
            <button className="works-card-play-btn" onClick={togglePlay} aria-label={isPlaying ? '暂停' : '播放'}>
              <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
                {isPlaying ? (<><rect x="6" y="4" width="4" height="16" rx="1" /><rect x="14" y="4" width="4" height="16" rx="1" /></>) : (<path d="M8 5v14l11-7z" />)}
              </svg>
            </button>
          </>
        ) : (
          <div className="works-card-placeholder">
            <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><polygon points="5 3 19 12 5 21 5 3" /></svg>
          </div>
        )}
        <div className="works-card-overlay" onClick={(e) => e.stopPropagation()}>
          <button className="works-card-action" title="导出" onClick={handleExport}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4" /><polyline points="7 10 12 15 17 10" /><line x1="12" y1="15" x2="12" y2="3" /></svg>
          </button>
          <button className="works-card-action" title="重命名" onClick={startRename}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round"><path d="M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z" /></svg>
          </button>
          <button className="works-card-action delete" title="删除" onClick={() => onDelete(product)}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><polyline points="3 6 5 6 21 6" /><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2" /></svg>
          </button>
        </div>
      </div>
      <div className="works-card-info">
        {isRenaming ? (
          <div className="works-card-rename">
            <input type="text" className="works-card-rename-input" value={editName} onChange={(e) => setEditName(e.target.value)} onKeyDown={handleKeyDown} onBlur={confirmRename} autoFocus />
            <span className="works-card-rename-ext">{getExtension(product.filename)}</span>
          </div>
        ) : (
          <div className="works-card-name" title={product.filename}>{getBaseName(product.filename)}</div>
        )}
        <div className="works-card-meta">
          {formatDateFriendly(product.created_at)} · {formatFileSize(product.file_size)}
          {product.duration > 0 && ` · ${formatDuration(product.duration)}`}
        </div>
      </div>
    </div>
  );
}

function DraftListItem({ draft, onClick, isEditing, editValue, onEdit, onSave, onChange, onDelete }: {
  draft: DraftItem;
  onClick: (id: string) => void;
  isEditing: boolean;
  editValue: string;
  onEdit: (e: React.MouseEvent) => void;
  onSave: () => void;
  onChange: (value: string) => void;
  onDelete: (e: React.MouseEvent) => void;
}) {
  return (
    <div className="draft-list-item" onClick={() => !isEditing && onClick(draft.id)}>
      <div className="draft-info">
        {isEditing ? (
          <input
            type="text"
            className="draft-title-input"
            value={editValue}
            onChange={e => onChange(e.target.value)}
            onBlur={onSave}
            onKeyDown={e => { if (e.key === 'Enter') {onSave();} if (e.key === 'Escape') {onSave();} }}
            autoFocus
            maxLength={30}
          />
        ) : (
          <div className="draft-title">{draft.title}</div>
        )}
        <div className="draft-meta">
          {draft.topic && <span className="draft-topic">{draft.topic}</span>}
          <span className="draft-date">{formatDateFriendly(draft.createdAt)}</span>
        </div>
      </div>
      {!isEditing && (
        <>
          <button className="draft-edit-btn" onClick={onEdit} title="重命名">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round"><path d="M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z" /></svg>
          </button>
          <button className="draft-delete-btn" onClick={onDelete} title="删除">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><polyline points="3 6 5 6 21 6" /><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2" /></svg>
          </button>
        </>
      )}
      <svg className="draft-arrow" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><polyline points="9 18 15 12 9 6"></polyline></svg>
    </div>
  );
}

export default function MyWorks() {
  const [activeTab, setActiveTab] = useState<TabType>('products');
  const [products, setProducts] = useState<ProductItem[]>([]);
  const [drafts, setDrafts] = useState<DraftItem[]>([]);
  const [loading, setLoading] = useState(true);
  const [showDeleteModal, setShowDeleteModal] = useState(false);
  const [deletingProduct, setDeletingProduct] = useState<ProductItem | null>(null);
  const [isDeleting, setIsDeleting] = useState(false);
  const [showDeleteDraftModal, setShowDeleteDraftModal] = useState(false);
  const [deletingDraft, setDeletingDraft] = useState<DraftItem | null>(null);
  const [isDeletingDraft, setIsDeletingDraft] = useState(false);

  const [editingDraftId, setEditingDraftId] = useState<string | null>(null);
  const [editDraftTitle, setEditDraftTitle] = useState('');
  const { navigate } = useNavigation();

  // ── 虚拟滚动 ───────────────────────────────────────────────
  const draftsListRef = useRef<HTMLDivElement>(null);
  const productsGridRef = useRef<HTMLDivElement>(null);

  // 成品网格列数（由容器宽度动态计算）
  const [productColumns, setProductColumns] = useState(4);

  useEffect(() => {
    const el = productsGridRef.current;
    if (!el) {return;}
    const ro = new ResizeObserver(entries => {
      const width = entries[0].contentRect.width;
      // 卡片最小 200px + gap 16px (var(--spacing-lg))
      setProductColumns(Math.max(1, Math.floor((width + 16) / 216)));
    });
    ro.observe(el);
    return () => ro.disconnect();
  }, []);

  // 草稿列表虚拟滚动（列表项高度约 64px）
  const draftsVirtualizer = useVirtualizer({
    count: drafts.length,
    getScrollElement: () => draftsListRef.current,
    estimateSize: () => 64,
    overscan: 5,
  });

  // 成品网格按行虚拟滚动（仅当数量超过阈值时启用，避免少量数据的开销）
  const enableProductVirtualization = products.length > 50;
  const productRowCount = Math.ceil(products.length / productColumns);
  const productsVirtualizer = useVirtualizer({
    count: productRowCount,
    getScrollElement: () => productsGridRef.current,
    estimateSize: () => 280,
    overscan: 2,
  });

  const loadProducts = async () => {
    try {
      const result = await invoke('list_local_products') as ApiResponse<ProductItem[]>;
      setProducts(result.data || []);
    } catch (error) {
      console.error('[MyWorks] Failed to load products:', error);
    }
  };

  const loadDrafts = async () => {
    try {
      const result = await invoke('list_local_projects') as ApiResponse<LocalProjectMeta[]>;
      const data = result.data || [];
      const draftItems: DraftItem[] = data.map(meta => ({ id: meta.id, title: meta.title || meta.id, createdAt: meta.createdAt, updatedAt: meta.updatedAt, topic: meta.topic }));
      draftItems.sort((a, b) => b.updatedAt - a.updatedAt);
      setDrafts(draftItems);
    } catch (error) {
      console.error('[MyWorks] Failed to load drafts:', error);
    }
  };

  useEffect(() => { async function loadAll() { await Promise.all([loadProducts(), loadDrafts()]); setLoading(false); } loadAll(); }, []);

  const handleRenameProduct = async (product: ProductItem, newFilename: string) => {
    await invoke('rename_local_product', { path: product.path, newFilename }) as ApiResponse<void>;
    await loadProducts();
  };

  const openDeleteModal = (product: ProductItem) => { setDeletingProduct(product); setShowDeleteModal(true); };

  const confirmDelete = async () => {
    if (!deletingProduct) {return;}
    setIsDeleting(true);
    await invoke('delete_local_product', { path: deletingProduct.path }) as ApiResponse<void>;
    await loadProducts();
    setShowDeleteModal(false);
    setDeletingProduct(null);
    setIsDeleting(false);
  };

  const openDeleteDraftModal = (e: React.MouseEvent, draft: DraftItem) => {
    e.stopPropagation();
    setDeletingDraft(draft);
    setShowDeleteDraftModal(true);
  };

  const confirmDeleteDraft = async () => {
    if (!deletingDraft) {return;}
    setIsDeletingDraft(true);
    try {
      await localProjectApi.deleteProject(deletingDraft.id);
      await loadDrafts();
    } catch (err) {
      console.error('[MyWorks] Failed to delete draft:', err);
    }
    setShowDeleteDraftModal(false);
    setDeletingDraft(null);
    setIsDeletingDraft(false);
  };

  const handleOpenDraft = async (draftId: string) => { await switchProject(draftId); navigate('video-creation'); };

  const handleEditDraft = (e: React.MouseEvent, draft: DraftItem) => {
    e.stopPropagation();
    setEditingDraftId(draft.id);
    setEditDraftTitle(draft.title);
  };

  const saveDraftTitle = async () => {
    if (!editingDraftId || !editDraftTitle.trim()) {
      setEditingDraftId(null);
      return;
    }
    try {
      const meta = await localProjectApi.loadMeta(editingDraftId);
      if (meta) {
        const updated: ProjectMeta = { ...meta, title: editDraftTitle.trim(), updatedAt: Date.now() };
        await localProjectApi.saveMeta(editingDraftId, updated);
        setDrafts(prev => prev.map(d => d.id === editingDraftId ? { ...d, title: editDraftTitle.trim(), updatedAt: Date.now() } : d));
      }
    } catch (err) {
      console.error('[MyWorks] Failed to save draft title:', err);
    }
    setEditingDraftId(null);
  };



  return (
    <div className="content-page content-page-compact">
      {/* 页面标题和 Tab 区域 */}
      <div className="works-header-wrapper">
        <div className="works-title-group">
          <h2>我的作品</h2>
          <p className="works-desc">管理已合成的视频成品和创作草稿</p>
        </div>

        <div className="works-tabs-bar">
          {tabs.map(tab => (
            <button key={tab.id} className={`works-tab-pill ${activeTab === tab.id ? 'active' : ''}`} onClick={() => { setActiveTab(tab.id); }}>
              {tab.label}<span className="works-tab-count">{tab.id === 'products' ? products.length : drafts.length}</span>
            </button>
          ))}
        </div>
      </div>

      {loading ? (
        <div className="empty-state"><p>加载中...</p></div>
      ) : (
        <>
          {activeTab === 'products' && (
            <>
              {products.length > 0 ? (
                <div ref={productsGridRef} className="works-grid" style={{ overflow: 'auto', flex: 1, minHeight: 0, display: enableProductVirtualization ? 'block' : 'grid', gridTemplateColumns: enableProductVirtualization ? undefined : `repeat(${productColumns}, 1fr)` }}>
                  {enableProductVirtualization ? (
                    <div style={{ height: `${productsVirtualizer.getTotalSize()}px`, position: 'relative', width: '100%' }}>
                      {productsVirtualizer.getVirtualItems().map(virtualRow => {
                        const startIdx = virtualRow.index * productColumns;
                        const rowProducts = products.slice(startIdx, startIdx + productColumns);
                        return (
                          <div
                            key={virtualRow.key}
                            style={{
                              position: 'absolute',
                              top: 0,
                              left: 0,
                              width: '100%',
                              height: `${virtualRow.size}px`,
                              transform: `translateY(${virtualRow.start}px)`,
                            }}
                          >
                            <div style={{ display: 'grid', gridTemplateColumns: `repeat(${productColumns}, 1fr)`, gap: 'var(--spacing-lg)', height: '100%' }}>
                              {rowProducts.map(product => (
                                <ProductCard key={product.path} product={product} onDelete={openDeleteModal} onRename={handleRenameProduct} />
                              ))}
                            </div>
                          </div>
                        );
                      })}
                    </div>
                  ) : (
                    products.map(product => (
                      <ProductCard key={product.path} product={product} onDelete={openDeleteModal} onRename={handleRenameProduct} />
                    ))
                  )}
                </div>
              ) : (
                <div className="empty-state-page">
                  <div className="empty-state-icon"><svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg></div>
                  <p className="empty-state-title">暂无成片</p>
                  <p className="empty-state-desc">完成压制成片后会保存在这里</p>
                </div>
              )}

            </>
          )}
          {activeTab === 'drafts' && (
            <>
              <div ref={draftsListRef} className="drafts-list-container" style={{ overflow: 'auto', flex: 1, minHeight: 0 }}>
                {drafts.length > 0 ? (
                  <div style={{ height: `${draftsVirtualizer.getTotalSize()}px`, position: 'relative', width: '100%' }}>
                    {draftsVirtualizer.getVirtualItems().map(virtualItem => {
                      const draft = drafts[virtualItem.index];
                      return (
                        <div
                          key={virtualItem.key}
                          style={{
                            position: 'absolute',
                            top: 0,
                            left: 0,
                            width: '100%',
                            transform: `translateY(${virtualItem.start}px)`,
                          }}
                        >
                          <DraftListItem
                            draft={draft}
                            onClick={handleOpenDraft}
                            isEditing={editingDraftId === draft.id}
                            editValue={editDraftTitle}
                            onEdit={e => handleEditDraft(e, draft)}
                            onSave={saveDraftTitle}
                            onChange={setEditDraftTitle}
                            onDelete={e => openDeleteDraftModal(e, draft)}
                          />
                        </div>
                      );
                    })}
                  </div>
                ) : (
                  <div className="empty-state-full">
                    <div className="empty-state-icon"><svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg></div>
                    <p className="empty-state-title">暂无草稿</p>
                    <p className="empty-state-desc">开始创作后会保存草稿在这里</p>
                  </div>
                )}
              </div>

            </>
          )}
        </>
      )}

      <ConfirmModal
        open={showDeleteModal && !!deletingProduct}
        type="danger"
        title={deletingProduct ? <>确认删除成品 <strong>「{deletingProduct.filename}」</strong> 吗？</> : ''}
        description="此操作不可撤销，文件将从本地磁盘删除"
        confirmText={isDeleting ? '删除中...' : '确认删除'}
        cancelText="取消"
        confirmButtonType="danger"
        onConfirm={confirmDelete}
        onCancel={() => !isDeleting && setShowDeleteModal(false)}
      />
      <ConfirmModal
        open={showDeleteDraftModal && !!deletingDraft}
        type="danger"
        title={deletingDraft ? <>确认删除草稿 <strong>「{deletingDraft.title}」</strong> 吗？</> : ''}
        description="此操作不可撤销，草稿及相关素材将从本地删除"
        confirmText={isDeletingDraft ? '删除中...' : '确认删除'}
        cancelText="取消"
        confirmButtonType="danger"
        onConfirm={confirmDeleteDraft}
        onCancel={() => !isDeletingDraft && setShowDeleteDraftModal(false)}
      />
    </div>
  );
}
