"use client";

import { useState, useRef, useEffect, useCallback } from "react";
import { ReportMaster } from "@/types/report";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Copy, Trash2, Edit, Eye, FileText, Calendar, User, Loader2, Pencil, AlignLeft } from "lucide-react";
import { reportApi } from "@/lib/api/reportApi";
import { useToast } from "@/hooks/use-toast";
import { useTabStore } from "@/stores/tabStore";
import { format } from "date-fns";
import { getTypeBgClass, getTypeLabel, getTypeIcon } from "@/lib/reportTypeColors";

interface ReportListTableProps {
  reports: ReportMaster[];
  total: number;
  page: number;
  limit: number;
  isLoading: boolean;
  viewMode: "grid" | "list";
  onPageChange: (page: number) => void;
  onRefresh: () => void;
  onViewClick: (report: ReportMaster) => void;
  onCopyClick: (report: ReportMaster) => void;
}

export function ReportListTable({
  reports,
  total,
  page,
  limit,
  isLoading,
  viewMode,
  onPageChange,
  onRefresh,
  onViewClick,
  onCopyClick,
}: ReportListTableProps) {
  const [deleteTarget, setDeleteTarget] = useState<string | null>(null);
  const [isDeleting, setIsDeleting] = useState(false);
  const { toast } = useToast();
  const openTab = useTabStore((s) => s.openTab);

  const totalPages = Math.ceil(total / limit);

  const handleEdit = (reportId: string) => {
    openTab({
      type: "admin",
      title: "리포트 디자이너",
      adminUrl: `/admin/screenMng/reportList/designer/${reportId}`,
    });
  };

  const handleDeleteConfirm = async () => {
    if (!deleteTarget) return;
    setIsDeleting(true);
    try {
      const response = await reportApi.deleteReport(deleteTarget);
      if (response.success) {
        toast({ title: "성공", description: "리포트가 삭제되었습니다." });
        setDeleteTarget(null);
        onRefresh();
      }
    } catch (error: any) {
      toast({
        title: "오류",
        description: error.message || "리포트 삭제에 실패했습니다.",
        variant: "destructive",
      });
    } finally {
      setIsDeleting(false);
    } 
  };

  const formatDate = (dateString: string | null) => {
    if (!dateString) return "-";
    try {
      return format(new Date(dateString), "yyyy-MM-dd");
    } catch {
      return dateString;
    }
  };

  const formatUpdatedDate = (updatedAt: string | null, createdAt: string | null) => {
    if (!updatedAt) return "-";
    try {
      const updatedStr = format(new Date(updatedAt), "yyyy-MM-dd HH:mm:ss");
      const createdStr = createdAt ? format(new Date(createdAt), "yyyy-MM-dd HH:mm:ss") : null;
      if (createdStr && updatedStr === createdStr) return "-";
      return format(new Date(updatedAt), "yyyy-MM-dd");
    } catch {
      return updatedAt || "-";
    }
  };

  if (isLoading) {
    return (
      <div className="flex h-72 items-center justify-center">
        <Loader2 className="text-muted-foreground h-10 w-10 animate-spin" />
      </div>
    );
  }

  if (reports.length === 0) {
    return (
      <div className="text-muted-foreground flex h-72 flex-col items-center justify-center gap-3">
        <FileText className="h-12 w-12 opacity-30" />
        <p className="text-base">등록된 리포트가 없습니다.</p>
      </div>
    );
  }

  const handleRename = async (reportId: string, newName: string) => {
    try {
      const response = await reportApi.updateReport(reportId, { reportNameKor: newName });
      if (response.success) {
        toast({ title: "성공", description: "리포트명이 변경되었습니다." });
        onRefresh();
      }
    } catch (error: any) {
      toast({
        title: "오류",
        description: error.message || "리포트명 변경에 실패했습니다.",
        variant: "destructive",
      });
    }
  };

  const handleDescriptionChange = async (reportId: string, newDesc: string) => {
    try {
      const response = await reportApi.updateReport(reportId, { description: newDesc });
      if (response.success) {
        toast({ title: "성공", description: "설명이 변경되었습니다." });
        onRefresh();
      }
    } catch (error: any) {
      toast({
        title: "오류",
        description: error.message || "설명 변경에 실패했습니다.",
        variant: "destructive",
      });
    }
  };

  return (
    <>
      {viewMode === "grid" ? (
        <GridView
          reports={reports}
          page={page}
          limit={limit}
          onEdit={handleEdit}
          onView={onViewClick}
          onCopyClick={onCopyClick}
          onDeleteClick={setDeleteTarget}
          onRename={handleRename}
          onDescriptionChange={handleDescriptionChange}
          formatDate={formatDate}
          formatUpdatedDate={formatUpdatedDate}
        />
      ) : (
        <ListView
          reports={reports}
          page={page}
          limit={limit}
          onEdit={handleEdit}
          onView={onViewClick}
          onCopyClick={onCopyClick}
          onDeleteClick={setDeleteTarget}
          onRename={handleRename}
          onDescriptionChange={handleDescriptionChange}
          formatDate={formatDate}
          formatUpdatedDate={formatUpdatedDate}
        />
      )}

      {/* 페이지네이션 */}
      <div className="flex items-center justify-between border-t border-gray-200 bg-gray-50 px-6 py-3">
        <span className="text-sm text-gray-500">
          총 <span className="font-semibold text-gray-900">{total}건</span>의 리포트
        </span>
        {totalPages > 1 && (
          <div className="flex items-center gap-1.5">
            {Array.from({ length: totalPages }, (_, i) => i + 1).map((p) => (
              <Button
                key={p}
                variant={p === page ? "default" : "outline"}
                size="sm"
                onClick={() => onPageChange(p)}
                className={`h-8 w-8 p-0 text-sm ${
                  p === page ? "bg-blue-600 text-white hover:bg-blue-700" : ""
                }`}
              >
                {p}
              </Button>
            ))}
          </div>
        )}
      </div>

      {/* 삭제 확인 다이얼로그 */}
      <AlertDialog open={deleteTarget !== null} onOpenChange={(open) => !open && setDeleteTarget(null)}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle className="text-lg">리포트 삭제</AlertDialogTitle>
            <AlertDialogDescription className="text-base">
              이 리포트를 삭제하시겠습니까?
              <br />
              삭제된 리포트는 복구할 수 없습니다.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={isDeleting} className="text-base">취소</AlertDialogCancel>
            <AlertDialogAction
              onClick={handleDeleteConfirm}
              disabled={isDeleting}
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90 text-base"
            >
              {isDeleting ? (
                <>
                  <Loader2 className="mr-2 h-5 w-5 animate-spin" />
                  삭제 중...
                </>
              ) : (
                "삭제"
              )}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </>
  );
}

interface ViewProps {
  reports: ReportMaster[];
  page: number;
  limit: number;
  onEdit: (id: string) => void;
  onView: (report: ReportMaster) => void;
  onCopyClick: (report: ReportMaster) => void;
  onDeleteClick: (id: string) => void;
  onRename: (reportId: string, newName: string) => Promise<void>;
  onDescriptionChange: (reportId: string, newDesc: string) => Promise<void>;
  formatDate: (d: string | null) => string;
  formatUpdatedDate: (updatedAt: string | null, createdAt: string | null) => string;
}

function InlineReportName({
  reportId,
  name,
  onNavigate,
  onRename,
}: {
  reportId: string;
  name: string;
  onNavigate: () => void;
  onRename: (reportId: string, newName: string) => Promise<void>;
}) {
  const [isEditing, setIsEditing] = useState(false);
  const [editValue, setEditValue] = useState(name);
  const [isSaving, setIsSaving] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (isEditing) {
      inputRef.current?.focus();
      inputRef.current?.select();
    }
  }, [isEditing]);

  const handleSave = useCallback(async () => {
    const trimmed = editValue.trim();
    if (!trimmed || trimmed === name) {
      setIsEditing(false);
      setEditValue(name);
      return;
    }
    setIsSaving(true);
    try {
      await onRename(reportId, trimmed);
    } finally {
      setIsSaving(false);
      setIsEditing(false);
    }
  }, [editValue, name, reportId, onRename]);

  const handleCancel = useCallback(() => {
    setIsEditing(false);
    setEditValue(name);
  }, [name]);

  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent) => {
      if (e.key === "Enter") {
        e.preventDefault();
        handleSave();
      } else if (e.key === "Escape") {
        handleCancel();
      }
    },
    [handleSave, handleCancel],
  );

  if (isEditing) {
    return (
      <div className="flex min-w-0 items-center gap-1.5">
        <Input
          ref={inputRef}
          value={editValue}
          onChange={(e) => setEditValue(e.target.value)}
          onKeyDown={handleKeyDown}
          onBlur={handleSave}
          disabled={isSaving}
          className="h-7 text-sm font-medium"
        />
        {isSaving && <Loader2 className="h-4 w-4 shrink-0 animate-spin text-gray-400" />}
      </div>
    );
  }

  return (
    <div className="group/name flex min-w-0 items-center gap-1.5">
      <button
        onClick={onNavigate}
        className="cursor-pointer truncate text-left text-sm font-semibold text-gray-900 hover:text-blue-600 hover:underline"
      >
        {name}
      </button>
      <button
        onClick={(e) => {
          e.stopPropagation();
          setIsEditing(true);
        }}
        className="shrink-0 rounded p-0.5 opacity-0 transition-opacity hover:bg-gray-100 group-hover/name:opacity-100"
        title="리포트명 수정"
      >
        <Pencil className="h-3.5 w-3.5 text-gray-400" />
      </button>
    </div>
  );
}

function InlineDescription({
  reportId,
  description,
  onSave,
}: {
  reportId: string;
  description: string | null;
  onSave: (reportId: string, newDesc: string) => Promise<void>;
}) {
  const [isEditing, setIsEditing] = useState(false);
  const [editValue, setEditValue] = useState(description || "");
  const [isSaving, setIsSaving] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (isEditing) {
      inputRef.current?.focus();
    }
  }, [isEditing]);

  const handleSave = useCallback(async () => {
    const trimmed = editValue.trim();
    if (trimmed === (description || "")) {
      setIsEditing(false);
      setEditValue(description || "");
      return;
    }
    setIsSaving(true);
    try {
      await onSave(reportId, trimmed);
    } finally {
      setIsSaving(false);
      setIsEditing(false);
    }
  }, [editValue, description, reportId, onSave]);

  const handleCancel = useCallback(() => {
    setIsEditing(false);
    setEditValue(description || "");
  }, [description]);

  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent) => {
      if (e.key === "Enter") {
        e.preventDefault();
        handleSave();
      } else if (e.key === "Escape") {
        handleCancel();
      }
    },
    [handleSave, handleCancel],
  );

  if (isEditing) {
    return (
      <div className="flex min-w-0 items-center gap-1.5">
        <Input
          ref={inputRef}
          value={editValue}
          onChange={(e) => setEditValue(e.target.value)}
          onKeyDown={handleKeyDown}
          onBlur={handleSave}
          disabled={isSaving}
          placeholder="설명 입력"
          className="h-6 text-xs"
        />
        {isSaving && <Loader2 className="h-4 w-4 shrink-0 animate-spin text-gray-400" />}
      </div>
    );
  }

  return (
    <div className="group/desc flex min-w-0 items-center gap-1.5">
      <span
        className="cursor-pointer truncate text-gray-500 hover:text-gray-700"
        onClick={() => setIsEditing(true)}
        title={description || "클릭하여 설명 입력"}
      >
        {description || <span className="italic text-gray-300">Inline Description</span>}
      </span>
      <button
        onClick={(e) => {
          e.stopPropagation();
          setIsEditing(true);
        }}
        className="shrink-0 rounded p-0.5 opacity-0 transition-opacity hover:bg-gray-100 group-hover/desc:opacity-100"
        title="설명 수정"
      >
        <Pencil className="h-3 w-3 text-gray-400" />
      </button>
    </div>
  );
}

function ListView({ reports, page, limit, onEdit, onView, onCopyClick, onDeleteClick, onRename, onDescriptionChange, formatDate, formatUpdatedDate }: ViewProps) {
  return (
    <div className="overflow-x-auto">
      <table className="w-full">
        <colgroup>
          <col style={{ width: 50 }} />
          <col style={{ width: "20%" }} />
          <col style={{ width: "15%" }} />
          <col style={{ width: 100 }} />
          <col style={{ width: 70 }} />
          <col style={{ width: 110 }} />
          <col style={{ width: 110 }} />
          <col style={{ width: 150 }} />
        </colgroup>
        <thead>
          <tr className="border-b border-gray-200 bg-gray-50">
            <th className="px-3 py-3 text-center text-sm font-semibold text-gray-500">NO</th>
            <th className="px-3 py-3 text-left text-sm font-semibold text-gray-500">리포트명</th>
            <th className="px-3 py-3 text-left text-sm font-semibold text-gray-500">설명</th>
            <th className="px-3 py-3 text-center text-sm font-semibold text-gray-500">카테고리</th>
            <th className="px-3 py-3 text-center text-sm font-semibold text-gray-500">작성자</th>
            <th className="px-3 py-3 text-center text-sm font-semibold text-gray-500">생성일</th>
            <th className="px-3 py-3 text-center text-sm font-semibold text-gray-500">수정일</th>
            <th className="px-3 py-3 text-center text-sm font-semibold text-gray-500">관리</th>
          </tr>
        </thead>
        <tbody className="divide-y divide-gray-100">
          {reports.map((report, index) => {
            const rowNumber = (page - 1) * limit + index + 1;
            return (
              <tr key={report.report_id} className="transition-colors hover:bg-blue-50/70">
                <td className="px-3 py-3.5 text-center text-sm font-medium text-gray-400">
                  {rowNumber}
                </td>
                <td className="px-3 py-3.5">
                  <div className="flex min-w-0 items-center gap-2.5">
                    <div className="flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-gradient-to-br from-blue-500 to-blue-600">
                      <FileText className="h-3 w-3 text-white" />
                    </div>
                    <InlineReportName
                      reportId={report.report_id}
                      name={report.report_name_kor}
                      onNavigate={() => onEdit(report.report_id)}
                      onRename={onRename}
                    />
                  </div>
                </td>
                <td className="min-w-0 overflow-hidden px-3 py-3.5">
                  <InlineDescription
                    reportId={report.report_id}
                    description={report.description}
                    onSave={onDescriptionChange}
                  />
                </td>
                <td className="px-3 py-3.5 text-center">
                  {report.report_type && (() => {
                    const TypeIcon = getTypeIcon(report.report_type);
                    return (
                      <Badge className={`gap-1.5 whitespace-nowrap text-sm leading-tight hover:bg-transparent ${getTypeBgClass(report.report_type)}`}>
                        <TypeIcon className="h-3.5 w-3.5" strokeWidth={2.2} />
                        {getTypeLabel(report.report_type)}
                      </Badge>
                    );
                  })()}
                </td>
                <td className="px-3 py-3.5 text-center text-sm text-gray-600">
                  {report.created_by || "-"}
                </td>
                <td className="whitespace-nowrap px-3 py-3.5 text-center text-sm text-gray-500">
                  {formatDate(report.created_at)}
                </td>
                <td className="whitespace-nowrap px-3 py-3.5 text-center text-sm text-gray-500">
                  {formatUpdatedDate(report.updated_at, report.created_at)}
                </td>
                <td className="px-3 py-3.5">
                  <div className="flex items-center justify-center gap-1">
                    <Button variant="ghost" size="icon" onClick={() => onView(report)} className="h-8 w-8" title="미리보기">
                      <Eye className="h-4 w-4 text-gray-500" strokeWidth={2} />
                    </Button>
                    <Button variant="ghost" size="icon" onClick={() => onEdit(report.report_id)} className="h-8 w-8" title="수정">
                      <Edit className="h-4 w-4 text-gray-500" strokeWidth={2} />
                    </Button>
                    <Button variant="ghost" size="icon" onClick={() => onCopyClick(report)} className="h-8 w-8" title="복사">
                      <Copy className="h-4 w-4 text-gray-500" strokeWidth={2} />
                    </Button>
                    <Button variant="ghost" size="icon" onClick={() => onDeleteClick(report.report_id)} className="h-8 w-8 text-red-500 hover:bg-red-50 hover:text-red-600" title="삭제">
                      <Trash2 className="h-4 w-4" strokeWidth={2} />
                    </Button>
                  </div>
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

function GridView({ reports, page, limit, onEdit, onView, onCopyClick, onDeleteClick, onRename, onDescriptionChange, formatDate, formatUpdatedDate }: ViewProps) {
  return (
    <div className="grid grid-cols-1 gap-3 px-4 py-4 md:grid-cols-2 lg:grid-cols-3">
      {reports.map((report, index) => {
        const rowNumber = (page - 1) * limit + index + 1;

        return (
          <div
            key={report.report_id}
            className="group rounded-lg border border-gray-200 bg-white px-4 py-3 transition-all hover:border-blue-300 hover:bg-blue-50/50 hover:shadow-md"
          >
            <div className="mb-2 flex items-center justify-between gap-2">
              <div className="ml-1 flex min-w-0 items-center gap-2">
                <div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-gradient-to-br from-blue-500 to-blue-600">
                  <FileText className="h-4 w-4 text-white" />
                </div>
                <InlineReportName
                  reportId={report.report_id}
                  name={report.report_name_kor}
                  onNavigate={() => onEdit(report.report_id)}
                  onRename={onRename}
                />
                {report.report_type && (() => {
                  const TypeIcon = getTypeIcon(report.report_type);
                  return (
                    <Badge className={`-ml-1.5 shrink-0 gap-1 text-[11px] leading-tight hover:bg-transparent ${getTypeBgClass(report.report_type)}`}>
                      <TypeIcon className="h-2.5 w-2.5" strokeWidth={2.5} />
                      {getTypeLabel(report.report_type)}
                    </Badge>
                  );
                })()}
              </div>
              <span className="shrink-0 text-[11px] font-medium text-gray-400">#{rowNumber}</span>
            </div>

            <div className="ml-3 space-y-1 text-xs">
              <div className="flex items-center text-gray-600">
                <User className="mr-1.5 h-3.5 w-3.5 shrink-0" />
                <span className="w-[38px] shrink-0 font-medium text-gray-700">작성자</span>
                <span>{report.created_by || "-"}</span>
              </div>
              <div className="flex items-center text-gray-600">
                <Calendar className="mr-1.5 h-3.5 w-3.5 shrink-0" />
                <span className="w-[38px] shrink-0 font-medium text-gray-700">생성일</span>
                <span>{formatDate(report.created_at)}</span>
              </div>
              <div className="flex items-center text-gray-600">
                <Calendar className="mr-1.5 h-3.5 w-3.5 shrink-0" />
                <span className="w-[38px] shrink-0 font-medium text-gray-700">수정일</span>
                <span>{formatUpdatedDate(report.updated_at, report.created_at)}</span>
              </div>
              <div className="flex items-center text-gray-600">
                <AlignLeft className="mr-1.5 h-3.5 w-3.5 shrink-0" />
                <span className="w-[38px] shrink-0 font-medium text-gray-700">설명</span>
                <div className="min-w-0 flex-1">
                  <InlineDescription
                    reportId={report.report_id}
                    description={report.description}
                    onSave={onDescriptionChange}
                  />
                </div>
              </div>
            </div>

            <div className="mt-2 flex gap-1.5 border-t border-gray-100 pt-2">
              <Button variant="outline" size="sm" onClick={() => onView(report)} className="h-7 flex-1 gap-1 px-0 text-[11px]">
                <Eye className="h-3 w-3" />
                미리보기
              </Button>
              <Button variant="outline" size="sm" onClick={() => onEdit(report.report_id)} className="h-7 flex-1 gap-1 px-0 text-[11px]">
                <Edit className="h-3 w-3" />
                수정
              </Button>
              <Button variant="outline" size="sm" onClick={() => onCopyClick(report)} className="h-7 flex-1 gap-1 px-0 text-[11px]">
                <Copy className="h-3 w-3" />
                복사
              </Button>
              <Button variant="outline" size="sm" onClick={() => onDeleteClick(report.report_id)} className="h-7 flex-1 gap-1 px-0 text-[11px] text-red-600 hover:border-red-200 hover:bg-red-50 hover:text-red-700">
                <Trash2 className="h-3 w-3" />
                삭제
              </Button>
            </div>
          </div>
        );
      })}
    </div>
  );
}
