"use client";

import { useState, useEffect, useCallback } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { MoreHorizontal, Trash2, Copy, Plus, Search, Network, Calendar } from "lucide-react";
import { toast } from "sonner";
import { showErrorToast } from "@/lib/utils/toastUtils";
import { useAuth } from "@/hooks/useAuth";
import { apiClient } from "@/lib/api/client";
import { ResponsiveDataView, RDVColumn, RDVCardField } from "@/components/common/ResponsiveDataView";

interface NodeFlow {
  flowId: number;
  flowName: string;
  flowDescription: string;
  createdAt: string;
  updatedAt: string;
}

interface DataFlowListProps {
  onLoadFlow: (flowId: number | null) => void;
}

export default function DataFlowList({ onLoadFlow }: DataFlowListProps) {
  const { user } = useAuth();
  const [flows, setFlows] = useState<NodeFlow[]>([]);
  const [loading, setLoading] = useState(true);
  const [searchTerm, setSearchTerm] = useState("");

  const [showDeleteModal, setShowDeleteModal] = useState(false);
  const [selectedFlow, setSelectedFlow] = useState<NodeFlow | null>(null);

  const loadFlows = useCallback(async () => {
    try {
      setLoading(true);
      const response = await apiClient.get("/dataflow/node-flows");

      if (response.data.success) {
        setFlows(response.data.data);
      } else {
        throw new Error(response.data.message || "플로우 목록 조회 실패");
      }
    } catch (error) {
      console.error("플로우 목록 조회 실패", error);
      showErrorToast("플로우 목록을 불러오는 데 실패했습니다", error, { guidance: "네트워크 연결을 확인해 주세요." });
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    loadFlows();
  }, [loadFlows]);

  const handleDelete = (flow: NodeFlow) => {
    setSelectedFlow(flow);
    setShowDeleteModal(true);
  };

  const handleCopy = async (flow: NodeFlow) => {
    try {
      setLoading(true);

      const response = await apiClient.get(`/dataflow/node-flows/${flow.flowId}`);

      if (!response.data.success) {
        throw new Error(response.data.message || "플로우 조회 실패");
      }

      const originalFlow = response.data.data;

      const copyResponse = await apiClient.post("/dataflow/node-flows", {
        flowName: `${flow.flowName} (복사본)`,
        flowDescription: flow.flowDescription,
        flowData: originalFlow.flowData,
      });

      if (copyResponse.data.success) {
        toast.success(`플로우가 성공적으로 복사되었습니다`);
        await loadFlows();
      } else {
        throw new Error(copyResponse.data.message || "플로우 복사 실패");
      }
    } catch (error) {
      console.error("플로우 복사 실패:", error);
      showErrorToast("플로우 복사에 실패했습니다", error, { guidance: "잠시 후 다시 시도해 주세요." });
    } finally {
      setLoading(false);
    }
  };

  const handleConfirmDelete = async () => {
    if (!selectedFlow) return;

    try {
      setLoading(true);
      const response = await apiClient.delete(`/dataflow/node-flows/${selectedFlow.flowId}`);

      if (response.data.success) {
        toast.success(`플로우가 삭제되었습니다: ${selectedFlow.flowName}`);
        await loadFlows();
      } else {
        throw new Error(response.data.message || "플로우 삭제 실패");
      }
    } catch (error) {
      console.error("플로우 삭제 실패:", error);
      showErrorToast("플로우 삭제에 실패했습니다", error, { guidance: "잠시 후 다시 시도해 주세요." });
    } finally {
      setLoading(false);
      setShowDeleteModal(false);
      setSelectedFlow(null);
    }
  };

  const filteredFlows = flows.filter(
    (flow) =>
      flow.flowName.toLowerCase().includes(searchTerm.toLowerCase()) ||
      flow.flowDescription.toLowerCase().includes(searchTerm.toLowerCase()),
  );

  // DropdownMenu 렌더러 (테이블 + 카드 공통)
  const renderDropdownMenu = (flow: NodeFlow) => (
    <div onClick={(e) => e.stopPropagation()}>
      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <Button variant="ghost" size="icon" className="h-8 w-8">
            <MoreHorizontal className="h-4 w-4" />
          </Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="end">
          <DropdownMenuItem onClick={() => onLoadFlow(flow.flowId)}>
            <Network className="mr-2 h-4 w-4" />
            불러오기
          </DropdownMenuItem>
          <DropdownMenuItem onClick={() => handleCopy(flow)}>
            <Copy className="mr-2 h-4 w-4" />
            복사
          </DropdownMenuItem>
          <DropdownMenuItem onClick={() => handleDelete(flow)} className="text-destructive">
            <Trash2 className="mr-2 h-4 w-4" />
            삭제
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>
    </div>
  );

  const columns: RDVColumn<NodeFlow>[] = [
    {
      key: "flowName",
      label: "플로우명",
      render: (_val, flow) => (
        <div className="flex items-center font-medium">
          <Network className="mr-2 h-4 w-4 text-primary" />
          {flow.flowName}
        </div>
      ),
    },
    {
      key: "flowDescription",
      label: "설명",
      render: (_val, flow) => (
        <span className="text-muted-foreground">{flow.flowDescription || "설명 없음"}</span>
      ),
    },
    {
      key: "createdAt",
      label: "생성일",
      render: (_val, flow) => (
        <span className="flex items-center text-muted-foreground">
          <Calendar className="mr-1 h-3 w-3" />
          {new Date(flow.createdAt).toLocaleDateString()}
        </span>
      ),
    },
    {
      key: "updatedAt",
      label: "최근 수정",
      hideOnMobile: true,
      render: (_val, flow) => (
        <span className="flex items-center text-muted-foreground">
          <Calendar className="mr-1 h-3 w-3" />
          {new Date(flow.updatedAt).toLocaleDateString()}
        </span>
      ),
    },
  ];

  const cardFields: RDVCardField<NodeFlow>[] = [
    {
      label: "생성일",
      render: (flow) => new Date(flow.createdAt).toLocaleDateString(),
    },
    {
      label: "최근 수정",
      render: (flow) => new Date(flow.updatedAt).toLocaleDateString(),
    },
  ];

  return (
    <div className="space-y-4">
      {/* 검색 및 액션 영역 */}
      <div className="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
        <div className="flex flex-col gap-4 sm:flex-row sm:items-center">
          <div className="w-full sm:w-[400px]">
            <div className="relative">
              <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
              <Input
                placeholder="플로우명, 설명으로 검색..."
                value={searchTerm}
                onChange={(e) => setSearchTerm(e.target.value)}
                className="h-10 pl-10 text-sm"
              />
            </div>
          </div>
        </div>

        <div className="flex items-center gap-4">
          <div className="text-sm text-muted-foreground">
            총 <span className="font-semibold text-foreground">{filteredFlows.length}</span> 건
          </div>
          <Button onClick={() => onLoadFlow(null)} className="h-10 gap-2 text-sm font-medium">
            <Plus className="h-4 w-4" />
            새 플로우 생성
          </Button>
        </div>
      </div>

      {/* 빈 상태: 커스텀 Empty UI */}
      {!loading && filteredFlows.length === 0 ? (
        <div className="flex h-64 flex-col items-center justify-center rounded-lg border bg-card shadow-sm">
          <div className="flex flex-col items-center gap-2 text-center">
            <div className="flex h-16 w-16 items-center justify-center rounded-full bg-muted">
              <Network className="h-8 w-8 text-muted-foreground" />
            </div>
            <h3 className="text-lg font-semibold">플로우가 없습니다</h3>
            <p className="max-w-sm text-sm text-muted-foreground">
              새 플로우를 생성하여 노드 기반 데이터 제어를 설계해보세요.
            </p>
            <Button onClick={() => onLoadFlow(null)} className="mt-4 h-10 gap-2 text-sm font-medium">
              <Plus className="h-4 w-4" />
              새 플로우 생성
            </Button>
          </div>
        </div>
      ) : (
        <ResponsiveDataView<NodeFlow>
          data={filteredFlows}
          columns={columns}
          keyExtractor={(flow) => String(flow.flowId)}
          isLoading={loading}
          skeletonCount={5}
          cardTitle={(flow) => (
            <span className="flex items-center">
              <Network className="mr-2 h-4 w-4 text-primary" />
              {flow.flowName}
            </span>
          )}
          cardSubtitle={(flow) => flow.flowDescription || "설명 없음"}
          cardHeaderRight={renderDropdownMenu}
          cardFields={cardFields}
          actionsLabel="작업"
          actionsWidth="80px"
          renderActions={renderDropdownMenu}
          onRowClick={(flow) => onLoadFlow(flow.flowId)}
        />
      )}

      {/* 삭제 확인 모달 */}
      <Dialog open={showDeleteModal} onOpenChange={setShowDeleteModal}>
        <DialogContent className="max-w-[95vw] sm:max-w-[500px]">
          <DialogHeader>
            <DialogTitle className="text-base sm:text-lg">플로우 삭제</DialogTitle>
            <DialogDescription className="text-xs sm:text-sm">
              &ldquo;{selectedFlow?.flowName}&rdquo; 플로우를 완전히 삭제하시겠습니까?
              <br />
              <span className="font-medium text-destructive">
                이 작업은 되돌릴 수 없으며, 모든 플로우 정보가 영구적으로 삭제됩니다.
              </span>
            </DialogDescription>
          </DialogHeader>
          <DialogFooter className="gap-2 sm:gap-0">
            <Button
              variant="outline"
              onClick={() => setShowDeleteModal(false)}
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
            >
              취소
            </Button>
            <Button
              variant="destructive"
              onClick={handleConfirmDelete}
              disabled={loading}
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
            >
              {loading ? "삭제 중..." : "삭제"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
