"use client";

import React, { useEffect, useState } from "react";
import { Plus, Pencil, Trash2, Play, FileText, RefreshCcw } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import {
  AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
  AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { useToast } from "@/hooks/use-toast";
import { FileReaderAPI, FileReaderConfig } from "@/lib/api/fileReader";
import { FileReaderConnectionModal } from "./FileReaderConnectionModal";

const RESULT_BADGE: Record<string, string> = {
  success: "bg-green-100 text-green-700",
  partial: "bg-amber-100 text-amber-700",
  failure: "bg-rose-100 text-rose-700",
  skipped: "bg-gray-100 text-gray-600",
};

export const FileReaderConnectionList: React.FC = () => {
  const { toast } = useToast();
  const [items, setItems] = useState<FileReaderConfig[]>([]);
  const [search, setSearch] = useState("");
  const [loading, setLoading] = useState(false);
  const [modalOpen, setModalOpen] = useState(false);
  const [editingId, setEditingId] = useState<number | null>(null);
  const [confirmDel, setConfirmDel] = useState<FileReaderConfig | null>(null);

  const load = async () => {
    setLoading(true);
    try {
      const list = await FileReaderAPI.list();
      setItems(list);
    } catch (e) {
      toast({ title: "조회 실패", description: (e as Error).message, variant: "destructive" });
    } finally {
      setLoading(false);
    }
  };
  useEffect(() => { void load(); }, []);

  const handleRunUpload = async (cfg: FileReaderConfig) => {
    const inp = document.createElement("input");
    inp.type = "file";
    inp.accept = ".csv,.tsv,.txt,.xlsx,.xls";
    inp.onchange = async () => {
      if (!inp.files || inp.files.length === 0) return;
      try {
        const r = await FileReaderAPI.runUpload(cfg.id!, inp.files[0]);
        toast({
          title: r.status === "failure" ? "적재 실패" : "적재 완료",
          description: `총 ${r.rowsTotal}행 / 성공 ${r.rowsInserted} / 실패 ${r.rowsFailed}`,
          variant: r.status === "failure" ? "destructive" : "default",
        });
        void load();
      } catch (e) {
        toast({ title: "실패", description: (e as Error).message, variant: "destructive" });
      }
    };
    inp.click();
  };

  const handleRunWatch = async (cfg: FileReaderConfig) => {
    try {
      const r = await FileReaderAPI.runWatch(cfg.id!);
      toast({
        title: "스캔 완료",
        description: `스캔 ${r.scanned} / 처리 ${r.processed} / 스킵 ${r.skipped} / 실패 ${r.failed}`,
      });
      void load();
    } catch (e) {
      toast({ title: "스캔 실패", description: (e as Error).message, variant: "destructive" });
    }
  };

  const filtered = items.filter(i =>
    !search || i.name.toLowerCase().includes(search.toLowerCase()) ||
    (i.target_table || "").toLowerCase().includes(search.toLowerCase())
  );

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between gap-2">
        <Input
          placeholder="이름/타겟 테이블로 검색"
          value={search}
          onChange={e => setSearch(e.target.value)}
          className="max-w-sm"
        />
        <div className="flex gap-2">
          <Button variant="outline" onClick={() => void load()} disabled={loading}>
            <RefreshCcw className="w-4 h-4 mr-1" /> 새로고침
          </Button>
          <Button onClick={() => { setEditingId(null); setModalOpen(true); }}>
            <Plus className="w-4 h-4 mr-1" /> 새 파일 리더
          </Button>
        </div>
      </div>

      {filtered.length === 0 ? (
        <div className="border rounded-md p-12 text-center text-muted-foreground">
          <FileText className="w-10 h-10 mx-auto mb-3 opacity-50" />
          등록된 파일 리더가 없습니다. "새 파일 리더" 버튼으로 추가하세요.
        </div>
      ) : (
        <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-3">
          {filtered.map(cfg => (
            <div key={cfg.id} className="border rounded-md p-4 bg-card flex flex-col gap-2">
              <div className="flex items-start justify-between gap-2">
                <div>
                  <div className="font-semibold text-base flex items-center gap-2">
                    <FileText className="w-4 h-4" /> {cfg.name}
                  </div>
                  <div className="text-xs text-muted-foreground mt-1">
                    {cfg.file_type.toUpperCase()} · {cfg.source_mode === "watch" ? "감시 폴더" : "업로드"} ·
                    {" "}target: {cfg.target_schema || "public"}.{cfg.target_table || "(미지정)"}
                  </div>
                </div>
                <Badge className={cfg.is_active === "Y" ? "bg-green-100 text-green-700" : "bg-gray-100 text-gray-500"}>
                  {cfg.is_active === "Y" ? "활성" : "비활성"}
                </Badge>
              </div>
              {cfg.source_mode === "watch" && cfg.host_path && (
                <div className="text-xs font-mono break-all text-muted-foreground">
                  📁 {cfg.host_path}/{cfg.file_pattern || "*"}
                </div>
              )}
              {cfg.last_run_at && (
                <div className="text-xs flex items-center gap-2">
                  <Badge className={RESULT_BADGE[cfg.last_run_result || ""] || "bg-gray-100"}>
                    {cfg.last_run_result || "-"}
                  </Badge>
                  <span className="text-muted-foreground">
                    {new Date(cfg.last_run_at).toLocaleString("ko-KR")} · 행 {cfg.last_processed_count || 0}
                  </span>
                </div>
              )}
              <div className="flex items-center gap-1 mt-2">
                {cfg.source_mode === "watch" ? (
                  <Button size="sm" variant="outline" onClick={() => handleRunWatch(cfg)}>
                    <Play className="w-3 h-3 mr-1" /> 지금 스캔
                  </Button>
                ) : (
                  <Button size="sm" variant="outline" onClick={() => handleRunUpload(cfg)}>
                    <Play className="w-3 h-3 mr-1" /> 업로드+적재
                  </Button>
                )}
                <Button size="sm" variant="ghost"
                  onClick={() => { setEditingId(cfg.id!); setModalOpen(true); }}>
                  <Pencil className="w-3 h-3" />
                </Button>
                <Button size="sm" variant="ghost"
                  onClick={() => setConfirmDel(cfg)}>
                  <Trash2 className="w-3 h-3 text-rose-600" />
                </Button>
              </div>
            </div>
          ))}
        </div>
      )}

      {modalOpen && (
        <FileReaderConnectionModal
          open={modalOpen}
          editingId={editingId}
          onClose={() => setModalOpen(false)}
          onSaved={() => { setModalOpen(false); void load(); }}
        />
      )}

      <AlertDialog open={!!confirmDel} onOpenChange={(o) => !o && setConfirmDel(null)}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>파일 리더 삭제</AlertDialogTitle>
            <AlertDialogDescription>
              "{confirmDel?.name}" 설정과 컬럼 매핑, 처리 이력을 모두 삭제합니다. 계속하시겠습니까?
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>취소</AlertDialogCancel>
            <AlertDialogAction
              onClick={async () => {
                if (!confirmDel) return;
                try {
                  await FileReaderAPI.remove(confirmDel.id!);
                  toast({ title: "삭제 완료" });
                  setConfirmDel(null);
                  void load();
                } catch (e) {
                  toast({ title: "삭제 실패", description: (e as Error).message, variant: "destructive" });
                }
              }}
            >삭제</AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
};

export default FileReaderConnectionList;
