import { useState, useEffect, useMemo } from 'react';
import { Card, CardContent } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Checkbox } from '@/components/ui/checkbox';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import {
  Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter,
} from '@/components/ui/dialog';
import {
  AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
  AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { PageHeader } from '@/components/shared/PageHeader';
import { DataTable } from '@/components/shared/DataTable';
import { Skeleton } from '@/components/ui/skeleton';
import {
  ClipboardList, Microscope, Search, MessageSquare, Plus, LoaderCircle,
  Archive, ArchiveRestore, Download, Pencil, Trash2,
} from 'lucide-react';
import {
  fetchBatches, createBatch, archiveBatches, unarchiveBatches, updateBatchName, deleteBatch,
} from '@/services/batchService';
import { createSourceFileDownloadUrl, deleteSourceFileById, listSourceFiles } from '@/services/sourceFileService';
import { BatchSummary, SourceFileRecord } from '@/types';
import { formatDate } from '@/lib/dateUtils';
import { describeSourceFileExtractionStatus } from '@/lib/sourceFileExtractionStatus';
import { formatFileSize } from '@/lib/sourceFileUtils';
import { useAuth } from '@/hooks/useAuth';
import { toast } from 'sonner';

const stageLabels = ['采购清单', '标准化', '搜索', '联系'];

export default function BatchManagement() {
  const { isAdmin } = useAuth();
  const [loading, setLoading] = useState(true);
  const [selectedBatch, setSelectedBatch] = useState<string | null>(null);
  const [batches, setBatches] = useState<BatchSummary[]>([]);
  const [detailLoading, setDetailLoading] = useState(false);
  const [batchSourceFiles, setBatchSourceFiles] = useState<SourceFileRecord[]>([]);
  const [downloadingSourceFileId, setDownloadingSourceFileId] = useState<string | null>(null);
  const [deletingSourceFileId, setDeletingSourceFileId] = useState<string | null>(null);

  // Tab state
  const [activeTab, setActiveTab] = useState<'active' | 'archived'>('active');

  // Multi-select
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
  const [archiving, setArchiving] = useState(false);

  // 新建批次对话框
  const [createOpen, setCreateOpen] = useState(false);
  const [createName, setCreateName] = useState('');
  const [creating, setCreating] = useState(false);

  // 编辑批次对话框
  const [editBatch, setEditBatch] = useState<BatchSummary | null>(null);
  const [editName, setEditName] = useState('');
  const [saving, setSaving] = useState(false);

  // 删除确认对话框
  const [deleteBatchTarget, setDeleteBatchTarget] = useState<BatchSummary | null>(null);
  const [deleting, setDeleting] = useState(false);

  const activeBatches = useMemo(() => batches.filter(b => !b.archived), [batches]);
  const archivedBatches = useMemo(() => batches.filter(b => b.archived), [batches]);
  const currentBatches = activeTab === 'active' ? activeBatches : archivedBatches;
  const selectedBatchSummary = useMemo(
    () => (selectedBatch ? batches.find(batch => batch.batch_id === selectedBatch) ?? null : null),
    [batches, selectedBatch],
  );

  const loadBatches = async () => {
    try {
      const data = await fetchBatches();
      setBatches(data);
    } catch (err) {
      console.error('Failed to fetch batches:', err);
    }
  };

  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        await loadBatches();
      } catch (err) {
        console.error('Failed to fetch batches:', err);
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, []);

  // Clear selection when switching tabs
  useEffect(() => {
    setSelectedIds(new Set());
  }, [activeTab]);

  async function handleCreateBatch() {
    setCreating(true);
    try {
      const batch = await createBatch({ name: createName });
      toast.success(`批次 ${batch.batch_id} 创建成功`);
      setCreateOpen(false);
      setCreateName('');
      await loadBatches();
    } catch (err) {
      console.error('Failed to create batch:', err);
      toast.error('创建批次失败，请重试。');
    } finally {
      setCreating(false);
    }
  }

  async function handleArchive() {
    if (selectedIds.size === 0) return;
    setArchiving(true);
    try {
      await archiveBatches(Array.from(selectedIds));
      toast.success(`已归档 ${selectedIds.size} 个批次`);
      setSelectedIds(new Set());
      await loadBatches();
    } catch (err) {
      console.error('Failed to archive batches:', err);
      toast.error('归档失败，请重试。');
    } finally {
      setArchiving(false);
    }
  }

  async function handleUnarchive() {
    if (selectedIds.size === 0) return;
    setArchiving(true);
    try {
      await unarchiveBatches(Array.from(selectedIds));
      toast.success(`已退回 ${selectedIds.size} 个批次`);
      setSelectedIds(new Set());
      await loadBatches();
    } catch (err) {
      console.error('Failed to unarchive batches:', err);
      toast.error('退回失败，请重试。');
    } finally {
      setArchiving(false);
    }
  }

  function toggleSelect(batchId: string) {
    setSelectedIds(prev => {
      const next = new Set(prev);
      if (next.has(batchId)) next.delete(batchId);
      else next.add(batchId);
      return next;
    });
  }

  function toggleSelectAll() {
    if (selectedIds.size === currentBatches.length) {
      setSelectedIds(new Set());
    } else {
      setSelectedIds(new Set(currentBatches.map(b => b.batch_id)));
    }
  }

  function openEditDialog(b: BatchSummary, e: React.MouseEvent) {
    e.stopPropagation();
    setEditBatch(b);
    setEditName(b.name || '');
  }

  async function handleSaveName() {
    if (!editBatch) return;
    setSaving(true);
    try {
      await updateBatchName(editBatch.batch_id, editName);
      toast.success('批次名称已更新');
      setEditBatch(null);
      setEditName('');
      await loadBatches();
    } catch (err) {
      console.error('Failed to update batch name:', err);
      toast.error('更新名称失败，请重试。');
    } finally {
      setSaving(false);
    }
  }

  function openDeleteConfirm(e: React.MouseEvent) {
    e.stopPropagation();
    if (editBatch) {
      setDeleteBatchTarget(editBatch);
    }
  }

  async function handleConfirmDelete() {
    if (!deleteBatchTarget) return;
    setDeleting(true);
    try {
      await deleteBatch(deleteBatchTarget.batch_id);
      toast.success(`批次 ${deleteBatchTarget.batch_id} 及其关联数据已删除`);
      setDeleteBatchTarget(null);
      setEditBatch(null);
      setEditName('');
      await loadBatches();
    } catch (err) {
      console.error('Failed to delete batch:', err);
      toast.error('删除批次失败，请重试。');
    } finally {
      setDeleting(false);
    }
  }

  async function handleDownloadSourceFile(record: SourceFileRecord) {
    setDownloadingSourceFileId(record.id);
    try {
      const signedUrl = await createSourceFileDownloadUrl(record.storage_path);
      window.open(signedUrl, '_blank', 'noopener,noreferrer');
    } catch (err) {
      console.error('Failed to download source file:', err);
      toast.error('下载原始资料失败，请重试。');
    } finally {
      setDownloadingSourceFileId(currentId => (currentId === record.id ? null : currentId));
    }
  }

  async function handleDeleteSourceFile(record: SourceFileRecord) {
    if (!window.confirm(`确定删除原始资料“${record.file_name}”吗？删除后将无法再下载该文件，且不会自动回滚已生成的下游数据。`)) {
      return;
    }

    setDeletingSourceFileId(record.id);
    try {
      const deletedRecord = await deleteSourceFileById(record.id);
      setBatchSourceFiles(prev => prev.filter(item => item.id !== record.id));
      if (deletedRecord) {
        setBatches(prev => prev.map(batch => (
          batch.batch_id === record.batch_id
            ? { ...batch, sourceFilesCount: Math.max(0, (batch.sourceFilesCount ?? 0) - 1) }
            : batch
        )));
        toast.success(`已删除原始资料：${record.file_name}`);
      } else {
        toast.success('原始资料已不存在');
      }
      void loadBatches().catch(error => {
        console.error('Failed to refresh batches after deleting source file:', error);
      });
    } catch (err) {
      console.error('Failed to delete source file:', err);
      toast.error('删除原始资料失败，请重试。');
    } finally {
      setDeletingSourceFileId(currentId => (currentId === record.id ? null : currentId));
    }
  }

  // Load batch detail data when a batch is selected
  useEffect(() => {
    if (!selectedBatch) return;
    let cancelled = false;
    setDetailLoading(true);
    setBatchSourceFiles([]);
    (async () => {
      try {
        const sourceFiles = await listSourceFiles(selectedBatch);
        if (!cancelled) {
          setBatchSourceFiles(sourceFiles);
        }
      } catch (err) {
        console.error('Failed to fetch batch details:', err);
        if (!cancelled) {
          toast.error('加载批次详情失败，请重试。');
        }
      } finally {
        if (!cancelled) {
          setDetailLoading(false);
        }
      }
    })();
    return () => { cancelled = true; };
  }, [selectedBatch]);

  if (loading) return <div className="space-y-4"><Skeleton className="h-8 w-40" />{[1,2,3].map(i => <Skeleton key={i} className="h-32" />)}</div>;

  if (selectedBatch) {
    const originalFileCount = detailLoading
      ? (selectedBatchSummary?.sourceFilesCount ?? batchSourceFiles.length)
      : batchSourceFiles.length;

    return (
      <div className="space-y-4">
        <div className="flex items-center gap-3">
          <button onClick={() => setSelectedBatch(null)} className="text-primary hover:underline text-sm">← 返回批次列表</button>
          <h1 className="text-xl font-bold text-primary">{selectedBatch}</h1>
        </div>

        <div className="rounded-2xl border border-border bg-background p-4 shadow-sm">
          <div className="mb-4 flex items-center justify-between">
            <div>
              <h2 className="text-base font-semibold text-foreground">原始资料</h2>
              <p className="text-sm text-muted-foreground">共 {originalFileCount} 个上传文件</p>
            </div>
          </div>

          {!detailLoading && batchSourceFiles.length === 0 ? (
            <div className="rounded-lg border border-dashed border-border bg-background py-16 text-center text-sm text-muted-foreground">
              暂无上传的原始资料
            </div>
          ) : (
            <DataTable
              columns={[
                { key: 'file_name', label: '文件名', sortable: true, truncate: true, defaultWidth: 360 },
                {
                  key: 'extraction_status',
                  label: '识别状态',
                  defaultWidth: 160,
                  render: (_: unknown, row: SourceFileRecord) => {
                    const status = describeSourceFileExtractionStatus(row);
                    return (
                      <div className="min-w-0">
                        <span className={`inline-flex max-w-full items-center rounded border px-1.5 py-0.5 text-xs ${status.badgeClassName}`}>
                          {status.label}
                        </span>
                        {status.detail ? (
                          <p className="mt-1 truncate text-xs text-muted-foreground">{status.detail}</p>
                        ) : null}
                      </div>
                    );
                  },
                },
                { key: 'size_bytes', label: '大小', sortable: true, render: (value: unknown) => formatFileSize(Number(value)), defaultWidth: 120 },
                { key: 'uploaded_by', label: '上传人', render: (value: unknown) => String(value || '未填写'), defaultWidth: 160 },
                { key: 'uploaded_at', label: '上传时间', sortable: true, render: (value: unknown) => formatDate(String(value)), defaultWidth: 180 },
                {
                  key: '_actions',
                  label: '操作',
                  defaultWidth: 180,
                  render: (_: unknown, row: SourceFileRecord) => {
                    const isDownloading = downloadingSourceFileId === row.id;
                    const isDeleting = deletingSourceFileId === row.id;

                    return (
                      <div className="flex items-center justify-center gap-1">
                        <Button
                          type="button"
                          variant="ghost"
                          size="sm"
                          className="h-8 px-2 text-primary"
                          onClick={() => handleDownloadSourceFile(row)}
                          disabled={isDownloading || isDeleting}
                        >
                          {isDownloading ? <LoaderCircle className="h-3.5 w-3.5 mr-1 animate-spin" /> : <Download className="h-3.5 w-3.5 mr-1" />}
                          下载
                        </Button>
                        <Button
                          type="button"
                          variant="ghost"
                          size="sm"
                          className="h-8 px-2 text-destructive hover:text-destructive"
                          onClick={() => handleDeleteSourceFile(row)}
                          disabled={isDownloading || isDeleting}
                        >
                          {isDeleting ? <LoaderCircle className="h-3.5 w-3.5 mr-1 animate-spin" /> : <Trash2 className="h-3.5 w-3.5 mr-1" />}
                          删除
                        </Button>
                      </div>
                    );
                  },
                },
              ]}
              data={batchSourceFiles}
              loading={detailLoading}
              rowKey={row => row.id}
            />
          )}
        </div>
      </div>
    );
  }

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <PageHeader title="批次管理" />
        <Button size="sm" className="h-9" onClick={() => setCreateOpen(true)}>
          <Plus className="h-4 w-4 mr-1" />新建批次
        </Button>
      </div>

      {/* 进行中 / 已归档 切换 */}
      <Tabs value={activeTab} onValueChange={v => setActiveTab(v as 'active' | 'archived')}>
        <div className="flex items-center justify-between">
          <TabsList>
            <TabsTrigger value="active">进行中 ({activeBatches.length})</TabsTrigger>
            <TabsTrigger value="archived">已归档 ({archivedBatches.length})</TabsTrigger>
          </TabsList>
          <div className="flex items-center gap-2">
            {currentBatches.length > 0 && (
              <Button variant="outline" size="sm" className="h-8 text-xs" onClick={toggleSelectAll}>
                {selectedIds.size === currentBatches.length ? '取消全选' : '全选'}
              </Button>
            )}
            {activeTab === 'active' && selectedIds.size > 0 && (
              <Button size="sm" className="h-8 text-xs" onClick={handleArchive} disabled={archiving}>
                {archiving ? <LoaderCircle className="h-3.5 w-3.5 mr-1 animate-spin" /> : <Archive className="h-3.5 w-3.5 mr-1" />}
                批次归档 ({selectedIds.size})
              </Button>
            )}
            {activeTab === 'archived' && selectedIds.size > 0 && (
              <Button size="sm" className="h-8 text-xs" onClick={handleUnarchive} disabled={archiving}>
                {archiving ? <LoaderCircle className="h-3.5 w-3.5 mr-1 animate-spin" /> : <ArchiveRestore className="h-3.5 w-3.5 mr-1" />}
                归档退回 ({selectedIds.size})
              </Button>
            )}
          </div>
        </div>

        <TabsContent value="active" className="mt-4">
          <div className="grid gap-4">
            {activeBatches.length === 0 && (
              <div className="text-center py-16 text-muted-foreground">暂无进行中的批次，请点击「新建批次」创建</div>
            )}
            {activeBatches.map(b => (
              <BatchCard
                key={b.batch_id}
                batch={b}
                selected={selectedIds.has(b.batch_id)}
                onToggleSelect={() => toggleSelect(b.batch_id)}
                onClick={() => setSelectedBatch(b.batch_id)}
                onEdit={e => openEditDialog(b, e)}
              />
            ))}
          </div>
        </TabsContent>
        <TabsContent value="archived" className="mt-4">
          <div className="grid gap-4">
            {archivedBatches.length === 0 && (
              <div className="text-center py-16 text-muted-foreground">暂无已归档的批次</div>
            )}
            {archivedBatches.map(b => (
              <BatchCard
                key={b.batch_id}
                batch={b}
                selected={selectedIds.has(b.batch_id)}
                onToggleSelect={() => toggleSelect(b.batch_id)}
                onClick={() => setSelectedBatch(b.batch_id)}
                onEdit={e => openEditDialog(b, e)}
              />
            ))}
          </div>
        </TabsContent>
      </Tabs>

      {/* 新建批次对话框 */}
      <Dialog open={createOpen} onOpenChange={nextOpen => { if (!nextOpen) { setCreateOpen(false); setCreateName(''); } }}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>新建批次</DialogTitle>
          </DialogHeader>
          <div className="space-y-4 py-2">
            <div className="space-y-2">
              <Label htmlFor="batch-name">批次名称（选填）</Label>
              <Input
                id="batch-name"
                placeholder="如：xxxx年x月采购"
                value={createName}
                onChange={e => setCreateName(e.target.value)}
                onKeyDown={e => { if (e.key === 'Enter' && !creating) handleCreateBatch(); }}
              />
              <p className="text-xs text-muted-foreground">批次 ID 将自动生成，名称仅用于方便识别。</p>
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => { setCreateOpen(false); setCreateName(''); }} disabled={creating}>取消</Button>
            <Button onClick={handleCreateBatch} disabled={creating}>
              {creating && <LoaderCircle className="h-4 w-4 mr-1 animate-spin" />}
              创建
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 编辑批次对话框 */}
      <Dialog open={editBatch !== null} onOpenChange={nextOpen => { if (!nextOpen) { setEditBatch(null); setEditName(''); } }}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>编辑批次</DialogTitle>
          </DialogHeader>
          {editBatch && (
            <div className="space-y-4 py-2">
              <div>
                <p className="text-sm text-muted-foreground">批次 ID</p>
                <p className="font-mono text-sm font-medium">{editBatch.batch_id}</p>
              </div>
              <div className="space-y-2">
                <Label htmlFor="edit-batch-name">批次名称</Label>
                <Input
                  id="edit-batch-name"
                  placeholder="如：xxxx年x月采购"
                  value={editName}
                  onChange={e => setEditName(e.target.value)}
                  onKeyDown={e => { if (e.key === 'Enter' && !saving) handleSaveName(); }}
                />
              </div>
            </div>
          )}
          <DialogFooter className="flex !justify-between">
            {isAdmin && (
              <Button variant="destructive" size="sm" onClick={openDeleteConfirm} disabled={saving || deleting}>
                <Trash2 className="h-4 w-4 mr-1" />删除批次
              </Button>
            )}
            <div className="flex gap-2">
              <Button variant="outline" onClick={() => { setEditBatch(null); setEditName(''); }} disabled={saving}>取消</Button>
              <Button onClick={handleSaveName} disabled={saving}>
                {saving && <LoaderCircle className="h-4 w-4 mr-1 animate-spin" />}
                保存
              </Button>
            </div>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 删除确认对话框 */}
      <AlertDialog open={deleteBatchTarget !== null} onOpenChange={nextOpen => { if (!nextOpen) setDeleteBatchTarget(null); }}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>确认删除批次</AlertDialogTitle>
            <AlertDialogDescription>
              即将删除批次 <strong className="text-foreground">{deleteBatchTarget?.batch_id}</strong> 及其关联的所有数据（原始资料、标准化结果、搜索结果、联系记录、源文件等）。此操作不可撤销。
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={deleting}>取消</AlertDialogCancel>
            <AlertDialogAction
              onClick={handleConfirmDelete}
              disabled={deleting}
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
            >
              {deleting && <LoaderCircle className="h-4 w-4 mr-1 animate-spin" />}
              确认删除
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}

/* ── Batch Card Component ────────────────────────────────────── */

interface BatchCardProps {
  batch: BatchSummary;
  selected: boolean;
  onToggleSelect: () => void;
  onClick: () => void;
  onEdit: (e: React.MouseEvent) => void;
}

function BatchCard({ batch: b, selected, onToggleSelect, onClick, onEdit }: BatchCardProps) {
  return (
    <Card className="card-hover cursor-pointer" onClick={onClick}>
      <CardContent className="p-5">
        <div className="flex items-start justify-between mb-3">
          <div className="flex items-start gap-3">
            <div className="pt-0.5" onClick={e => e.stopPropagation()}>
              <Checkbox checked={selected} onCheckedChange={onToggleSelect} />
            </div>
            <div>
              <h3 className="font-mono font-bold text-primary">{b.batch_id}</h3>
              {b.name && <p className="text-sm text-foreground mt-0.5">{b.name}</p>}
              <p className="text-xs text-muted-foreground mt-0.5">{formatDate(b.created_at)}</p>
            </div>
          </div>
          <div className="flex items-center gap-2">
            <Button variant="ghost" size="icon" className="h-8 w-8" onClick={onEdit} title="编辑批次">
              <Pencil className="h-4 w-4" />
            </Button>
            <Badge variant="outline">阶段 {b.stage}/4</Badge>
          </div>
        </div>
        <div className="grid grid-cols-4 gap-3 mb-3 text-center">
          <div className="bg-muted rounded-md p-2">
            <ClipboardList className="h-4 w-4 mx-auto mb-1 text-primary" />
            <p className="text-lg font-bold text-foreground">{b.sourceFilesCount ?? b.materialsCount}</p>
            <p className="text-[10px] text-muted-foreground">原始资料</p>
          </div>
          <div className="bg-muted rounded-md p-2">
            <Microscope className="h-4 w-4 mx-auto mb-1 text-primary" />
            <p className="text-lg font-bold text-foreground">{b.standardizedCount}</p>
            <p className="text-[10px] text-muted-foreground">标准化</p>
          </div>
          <div className="bg-muted rounded-md p-2">
            <Search className="h-4 w-4 mx-auto mb-1 text-primary" />
            <p className="text-lg font-bold text-foreground">{b.searchResultsCount}</p>
            <p className="text-[10px] text-muted-foreground">搜索结果</p>
          </div>
          <div className="bg-muted rounded-md p-2">
            <MessageSquare className="h-4 w-4 mx-auto mb-1 text-primary" />
            <p className="text-lg font-bold text-foreground">{b.contactLogsCount}</p>
            <p className="text-[10px] text-muted-foreground">联系记录</p>
          </div>
        </div>
        <div className="flex items-center gap-1">
          {stageLabels.map((label, i) => (
            <div key={i} className="flex items-center gap-1 flex-1">
              <div className={`h-1.5 flex-1 rounded-full ${i < b.stage ? 'bg-primary' : 'bg-muted'}`} />
              <span className={`text-[9px] ${i < b.stage ? 'text-primary' : 'text-muted-foreground'}`}>{label}</span>
            </div>
          ))}
        </div>
      </CardContent>
    </Card>
  );
}
