"use client";

/**
 * 테이블 이력 뷰어 모달
 * 테이블 타입 관리의 {테이블명}_log 테이블 데이터를 표시
 */

import React, { useEffect, useState } from "react";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Badge } from "@/components/ui/badge";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Clock, User, FileEdit, Trash2, Plus, AlertCircle, Loader2, Search, X } from "lucide-react";
import {
  getRecordHistory,
  getRecordTimeline,
  TableHistoryRecord,
  TableHistoryTimelineEvent,
} from "@/lib/api/tableHistory";
import { format } from "date-fns";
import { ko } from "date-fns/locale";

interface TableHistoryModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  tableName: string;
  recordId?: string | number | null; // 선택사항: null이면 전체 테이블 이력
  recordLabel?: string;
  displayColumn?: string; // 전체 이력에서 레코드 구분용 컬럼 (예: device_code, name)
}

export function TableHistoryModal({
  open,
  onOpenChange,
  tableName,
  recordId,
  recordLabel,
  displayColumn,
}: TableHistoryModalProps) {
  const [loading, setLoading] = useState(false);
  const [timeline, setTimeline] = useState<TableHistoryTimelineEvent[]>([]);
  const [detailRecords, setDetailRecords] = useState<TableHistoryRecord[]>([]);
  const [allRecords, setAllRecords] = useState<TableHistoryRecord[]>([]); // 검색용 원본 데이터
  // recordId가 없으면 (전체 테이블 모드) detail 탭부터 시작
  const [activeTab, setActiveTab] = useState<"timeline" | "detail">(recordId ? "timeline" : "detail");
  const [error, setError] = useState<string | null>(null);
  const [searchTerm, setSearchTerm] = useState<string>(""); // 검색어

  useEffect(() => {
    if (open) {
      loadHistory();
      // recordId 변경 시 탭도 초기화
      setActiveTab(recordId ? "timeline" : "detail");
    }
  }, [open, tableName, recordId]);

  const loadHistory = async () => {
    setLoading(true);
    setError(null);

    try {
      if (recordId) {
        // 단일 레코드 이력 로드
        const [timelineRes, detailRes] = await Promise.all([
          getRecordTimeline(tableName, recordId),
          getRecordHistory(tableName, recordId, { limit: 100 }),
        ]);

        if (timelineRes.success && timelineRes.data) {
          setTimeline(timelineRes.data);
        } else {
          setError(timelineRes.error || "타임라인 로드 실패");
        }

        if (detailRes.success && detailRes.data) {
          setDetailRecords(detailRes.data.records);
          setAllRecords(detailRes.data.records);
        }
      } else {
        // 전체 테이블 이력 로드 (recordId 없이)
        const detailRes = await getRecordHistory(tableName, null, { limit: 200 });

        if (detailRes.success && detailRes.data) {
          const records = detailRes.data.records;
          setAllRecords(records); // 원본 데이터 저장
          setDetailRecords(records); // 초기 표시 데이터
          // 타임라인은 전체 테이블에서는 사용하지 않음
          setTimeline([]);
        } else {
          setError(detailRes.error || "이력 로드 실패");
        }
      }
    } catch (err: any) {
      setError(err.message || "이력 로드 중 오류 발생");
    } finally {
      setLoading(false);
    }
  };

  const getOperationIcon = (type: string) => {
    switch (type) {
      case "INSERT":
        return <Plus className="h-4 w-4 text-emerald-600" />;
      case "UPDATE":
        return <FileEdit className="h-4 w-4 text-primary" />;
      case "DELETE":
        return <Trash2 className="h-4 w-4 text-destructive" />;
      default:
        return <Clock className="h-4 w-4 text-muted-foreground" />;
    }
  };

  const getOperationBadge = (type: string) => {
    switch (type) {
      case "INSERT":
        return <span className="text-sm font-medium text-emerald-600">추가</span>;
      case "UPDATE":
        return <span className="text-sm font-medium text-primary">수정</span>;
      case "DELETE":
        return <span className="text-sm font-medium text-destructive">삭제</span>;
      default:
        return <span className="text-sm font-medium text-muted-foreground">{type}</span>;
    }
  };

  const formatDate = (dateString: string) => {
    try {
      const date = new Date(dateString);

      // 🚨 타임존 보정 로직
      // 실 서비스 DB는 UTC로 저장되는데, 프론트엔드에서 이를 KST로 인식하지 못하고
      // UTC 시간 그대로(예: 02:55)를 한국 시간 02:55로 보여주는 문제가 있음 (9시간 느림).
      // 반면 로컬 DB는 이미 KST로 저장되어 있어서 변환하면 안 됨.
      // 따라서 로컬 환경이 아닐 때만 강제로 9시간을 더해줌.
      const isLocal =
        typeof window !== "undefined" &&
        (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1");

      if (!isLocal) {
        date.setHours(date.getHours() + 9);
      }

      return format(date, "yyyy년 MM월 dd일 HH:mm:ss", { locale: ko });
    } catch {
      return dateString;
    }
  };

  // 검색 필터링 (전체 테이블 모드에서만)
  const handleSearch = (term: string) => {
    setSearchTerm(term);

    if (!term.trim()) {
      // 검색어가 없으면 전체 표시
      setDetailRecords(allRecords);
      return;
    }

    const lowerTerm = term.toLowerCase();
    const filtered = allRecords.filter((record) => {
      // 레코드 ID로 검색
      if (record.original_id?.toString().toLowerCase().includes(lowerTerm)) {
        return true;
      }

      // displayColumn 값으로 검색 (full_row_after에서 추출)
      if (displayColumn && record.full_row_after) {
        const displayValue = record.full_row_after[displayColumn];
        if (displayValue && displayValue.toString().toLowerCase().includes(lowerTerm)) {
          return true;
        }
      }

      // 변경자로 검색
      if (record.changed_by?.toLowerCase().includes(lowerTerm)) {
        return true;
      }

      // 컬럼명으로 검색
      if (record.changed_column?.toLowerCase().includes(lowerTerm)) {
        return true;
      }

      return false;
    });

    setDetailRecords(filtered);
  };

  // displayColumn 값 추출 헬퍼 함수
  const getDisplayValue = (record: TableHistoryRecord): string | null => {
    if (!displayColumn) return null;

    // full_row_after에서 먼저 시도
    if (record.full_row_after && record.full_row_after[displayColumn]) {
      return record.full_row_after[displayColumn];
    }

    // full_row_before에서 시도 (DELETE의 경우)
    if (record.full_row_before && record.full_row_before[displayColumn]) {
      return record.full_row_before[displayColumn];
    }

    return null;
  };

  // 단일 레코드 모드에서 displayColumn 값 가져오기
  const recordDisplayValue =
    recordId && displayColumn && detailRecords.length > 0 ? getDisplayValue(detailRecords[0]) : null;

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-h-[90vh] max-w-[95vw] sm:max-w-[900px]">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2 text-base sm:text-lg">
            <Clock className="h-5 w-5" />
            변경 이력{" "}
            {!recordId && (
              <Badge variant="secondary" className="text-xs">
                전체
              </Badge>
            )}
          </DialogTitle>
          <DialogDescription className="text-xs sm:text-sm">
            {recordId
              ? `${recordDisplayValue || recordLabel || "-"} - ${tableName} 테이블`
              : `${tableName} 테이블 전체 이력`}
          </DialogDescription>
        </DialogHeader>

        {loading ? (
          <div className="flex items-center justify-center py-12">
            <Loader2 className="text-primary h-8 w-8 animate-spin" />
            <span className="text-muted-foreground ml-2 text-sm">로딩 중...</span>
          </div>
        ) : error ? (
          <div className="flex flex-col items-center justify-center py-12">
            <AlertCircle className="text-destructive mb-4 h-12 w-12" />
            <p className="text-destructive text-sm">{error}</p>
            <Button variant="outline" onClick={loadHistory} className="mt-4 h-8 text-xs sm:h-10 sm:text-sm">
              다시 시도
            </Button>
          </div>
        ) : (
          <Tabs value={activeTab} onValueChange={(v) => setActiveTab(v as any)} className="w-full">
            {recordId && (
              <TabsList className="w-full">
                <TabsTrigger value="timeline" className="flex-1 text-xs sm:text-sm">
                  타임라인 ({timeline.length})
                </TabsTrigger>
                <TabsTrigger value="detail" className="flex-1 text-xs sm:text-sm">
                  상세 내역 ({detailRecords.length})
                </TabsTrigger>
              </TabsList>
            )}
            {!recordId && (
              <>
                <TabsList className="w-full">
                  <TabsTrigger value="detail" className="flex-1 text-xs sm:text-sm">
                    전체 변경 이력 ({detailRecords.length})
                  </TabsTrigger>
                </TabsList>

                {/* 검색창 (전체 테이블 모드) */}
                <div className="relative mt-4">
                  <Search className="text-muted-foreground absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2" />
                  <Input
                    placeholder={`레코드 ID${displayColumn ? `, ${displayColumn}` : ""}, 변경자, 컬럼명으로 검색...`}
                    value={searchTerm}
                    onChange={(e) => handleSearch(e.target.value)}
                    className="h-9 pr-10 pl-10 text-xs sm:h-10 sm:text-sm"
                  />
                  {searchTerm && (
                    <button
                      onClick={() => handleSearch("")}
                      className="text-muted-foreground hover:text-foreground absolute top-1/2 right-3 -translate-y-1/2"
                    >
                      <X className="h-4 w-4" />
                    </button>
                  )}
                </div>

                {searchTerm && (
                  <p className="text-muted-foreground mt-2 text-xs">
                    검색 결과: {detailRecords.length}개 / 전체 {allRecords.length}개
                  </p>
                )}
              </>
            )}

            {/* 타임라인 뷰 */}
            <TabsContent value="timeline">
              <ScrollArea className="h-[500px] w-full rounded-md border p-4">
                {timeline.length === 0 ? (
                  <div className="flex flex-col items-center justify-center py-12 text-center">
                    <Clock className="text-muted-foreground mb-2 h-12 w-12" />
                    <p className="text-muted-foreground text-sm">변경 이력이 없습니다</p>
                  </div>
                ) : (
                  <div className="space-y-6">
                    {timeline.map((event, index) => (
                      <div key={index} className="relative border-l-2 border-border pb-6 pl-8 last:border-l-0">
                        <div className="absolute top-0 -left-3 rounded-full border-2 border-border bg-white p-1">
                          {getOperationIcon(event.operation_type)}
                        </div>

                        <div className="space-y-2">
                          <div className="flex items-center justify-between">
                            {getOperationBadge(event.operation_type)}
                            <span className="text-muted-foreground text-xs">{formatDate(event.changed_at)}</span>
                          </div>

                          <div className="flex items-center gap-2 text-sm">
                            <User className="text-muted-foreground h-3 w-3" />
                            <span className="font-medium">{event.changed_by}</span>
                            {event.ip_address && (
                              <span className="text-muted-foreground text-xs">({event.ip_address})</span>
                            )}
                          </div>

                          {event.changes && event.changes.length > 0 && (
                            <div className="mt-3 space-y-2">
                              <p className="text-muted-foreground text-xs font-medium">변경된 항목:</p>
                              <div className="space-y-1">
                                {event.changes.map((change, idx) => (
                                  <div key={idx} className="rounded bg-muted p-2 text-xs">
                                    <span className="font-mono font-medium">{change.column}</span>
                                    <div className="mt-1 flex items-center gap-2">
                                      <span className="text-destructive line-through">{change.oldValue || "(없음)"}</span>
                                      <span>→</span>
                                      <span className="font-medium text-emerald-600">{change.newValue || "(없음)"}</span>
                                    </div>
                                  </div>
                                ))}
                              </div>
                            </div>
                          )}
                        </div>
                      </div>
                    ))}
                  </div>
                )}
              </ScrollArea>
            </TabsContent>

            {/* 상세 내역 뷰 */}
            <TabsContent value="detail">
              <ScrollArea className="h-[500px] w-full rounded-md border">
                {detailRecords.length === 0 ? (
                  <div className="flex flex-col items-center justify-center py-12 text-center">
                    <FileEdit className="text-muted-foreground mb-2 h-12 w-12" />
                    <p className="text-muted-foreground text-sm">변경 내역이 없습니다</p>
                  </div>
                ) : (
                  <table className="w-full text-xs">
                    <thead className="sticky top-0 border-b bg-muted">
                      <tr>
                        {!recordId && <th className="p-2 text-left font-medium">레코드</th>}
                        <th className="p-2 text-left font-medium">작업</th>
                        <th className="p-2 text-left font-medium">컬럼</th>
                        <th className="p-2 text-left font-medium">이전 값</th>
                        <th className="p-2 text-left font-medium">새 값</th>
                        <th className="p-2 text-left font-medium">변경자</th>
                        <th className="p-2 text-left font-medium">일시</th>
                      </tr>
                    </thead>
                    <tbody>
                      {detailRecords.map((record) => {
                        const displayValue = getDisplayValue(record);
                        return (
                          <tr key={record.log_id} className="border-b hover:bg-muted">
                            {!recordId && (
                              <td className="p-2">
                                {displayValue ? (
                                  <span className="font-medium text-foreground">{displayValue}</span>
                                ) : (
                                  <span className="text-muted-foreground text-xs">-</span>
                                )}
                              </td>
                            )}
                            <td className="p-2">{getOperationBadge(record.operation_type)}</td>
                            <td className="p-2 font-mono">{record.changed_column}</td>
                            <td className="max-w-[200px] truncate p-2 text-destructive">{record.old_value || "-"}</td>
                            <td className="max-w-[200px] truncate p-2 text-emerald-600">{record.new_value || "-"}</td>
                            <td className="p-2">{record.changed_by}</td>
                            <td className="text-muted-foreground p-2">{formatDate(record.changed_at)}</td>
                          </tr>
                        );
                      })}
                    </tbody>
                  </table>
                )}
              </ScrollArea>
            </TabsContent>
          </Tabs>
        )}

        <div className="flex justify-end gap-2 pt-4">
          <Button variant="outline" onClick={() => onOpenChange(false)} className="h-8 text-xs sm:h-10 sm:text-sm">
            닫기
          </Button>
        </div>
      </DialogContent>
    </Dialog>
  );
}
