/**
 * V3 DataView Renderer
 * - 자체적으로 데이터를 fetching하고 테이블로 표시
 * - entityJoinApi 사용
 * - v2EventBus TABLE_REFRESH 이벤트 구독
 * - 페이징, 정렬, 행 선택 지원
 */

"use client";

import React, { useState, useEffect } from "react";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Button } from "@/components/ui/button";
import { DataViewComponentConfig } from "@/lib/api/metaComponent";
import { entityJoinApi } from "@/lib/api/entityJoin";
import { v2EventBus } from "@/lib/v2-core/events/EventBus";
import { V2_EVENTS } from "@/lib/v2-core/events/types";
import { cn } from "@/lib/utils";
import { ChevronLeft, ChevronRight, ArrowUp, ArrowDown, Loader2 } from "lucide-react";

interface DataViewRendererProps {
  id: string;
  config: DataViewComponentConfig;
  selectedRowsData?: any[];
  onSelectedRowsChange?: (rows: any[], data: any[]) => void;
  formData?: Record<string, any>;
  onFormDataChange?: (fieldName: string, value: any) => void;
  tableName?: string;
  companyCode?: string;
  screenId?: number;
  isDesignMode?: boolean;
  className?: string;
  onRefresh?: () => void;
}

interface SortState {
  column: string | null;
  order: "asc" | "desc";
}

export function DataViewRenderer({
  id,
  config,
  selectedRowsData = [],
  onSelectedRowsChange,
  formData,
  onFormDataChange,
  tableName,
  companyCode,
  screenId,
  isDesignMode = false,
  className,
  onRefresh,
}: DataViewRendererProps) {
  // 상태 관리
  const [data, setData] = useState<any[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [currentPage, setCurrentPage] = useState(1);
  const [totalCount, setTotalCount] = useState(0);
  const [sortState, setSortState] = useState<SortState>({ column: null, order: "asc" });
  const [selectedRowIds, setSelectedRowIds] = useState<Set<string | number>>(new Set());
  const [filters, setFilters] = useState<Record<string, any>>({}); // 🔍 검색 필터

  const pageSize = config.pageSize || 10;
  const totalPages = Math.ceil(totalCount / pageSize);
  const targetTableName = config.tableName || tableName;

  // 데이터 로드 함수
  const loadData = async () => {
    if (isDesignMode || !targetTableName) {
      return;
    }

    setLoading(true);
    setError(null);

    try {
      // 🔍 filters를 search 파라미터로 전달
      const response = await entityJoinApi.getTableDataWithJoins(targetTableName, {
        page: currentPage,
        size: pageSize,
        sortBy: sortState.column || undefined,
        sortOrder: sortState.order,
        enableEntityJoin: true,
        companyCodeOverride: companyCode,
        search: Object.keys(filters).length > 0 ? filters : undefined, // 필터가 있으면 전달
      });

      setData(response.data || []);
      setTotalCount(response.total || 0);
    } catch (err: any) {
      console.error("DataViewRenderer: 데이터 로드 실패", err);
      setError(err.message || "데이터를 불러오는 중 오류가 발생했습니다.");
      setData([]);
      setTotalCount(0);
    } finally {
      setLoading(false);
    }
  };

  // 컬럼 목록 추출 (config.columns 또는 데이터에서 자동 추출)
  const columns = React.useMemo(() => {
    if (config.columns && config.columns.length > 0) {
      return config.columns;
    }

    // 첫 번째 데이터 행에서 컬럼 자동 추출
    if (data.length > 0) {
      const firstRow = data[0];
      return Object.keys(firstRow).map((key) => ({
        columnName: key,
        columnLabel: key,
        visible: true,
      }));
    }

    return [];
  }, [config.columns, data]);

  // 마운트 시 + tableName/page/sort/filters 변경 시 데이터 로드
  useEffect(() => {
    loadData();
  }, [targetTableName, currentPage, sortState, filters]);

  // TABLE_REFRESH 이벤트 구독
  useEffect(() => {
    const unsubscribe = v2EventBus.subscribe(
      V2_EVENTS.TABLE_REFRESH,
      (payload) => {
        // 모든 테이블 새로고침 또는 특정 테이블만
        if (!payload.tableName || payload.tableName === targetTableName) {
          console.log(`DataViewRenderer: TABLE_REFRESH 이벤트 수신 (${targetTableName})`, payload);
          
          // 🔍 필터가 전달되면 적용
          if (payload.filters !== undefined) {
            setFilters(payload.filters);
            setCurrentPage(1); // 필터 변경 시 첫 페이지로
          } else {
            // 필터 없으면 그냥 새로고침
            loadData();
          }

          if (onRefresh) {
            onRefresh();
          }
        }
      },
      { componentId: id }
    );

    return () => {
      unsubscribe();
    };
  }, [id, targetTableName]);

  // 컬럼 헤더 클릭 (정렬 전환)
  const handleSort = (columnName: string) => {
    setSortState((prev) => {
      if (prev.column === columnName) {
        // 같은 컬럼: ASC → DESC → null
        if (prev.order === "asc") {
          return { column: columnName, order: "desc" };
        } else {
          return { column: null, order: "asc" };
        }
      } else {
        // 다른 컬럼: ASC로 시작
        return { column: columnName, order: "asc" };
      }
    });
    setCurrentPage(1); // 정렬 변경 시 첫 페이지로
  };

  // 행 클릭 (선택)
  const handleRowClick = (row: any, rowIndex: number) => {
    const rowId = row.id || rowIndex;

    const newSelectedIds = new Set(selectedRowIds);
    if (newSelectedIds.has(rowId)) {
      newSelectedIds.delete(rowId);
    } else {
      newSelectedIds.add(rowId);
    }

    setSelectedRowIds(newSelectedIds);

    // 선택된 행 데이터 전달
    const selectedRows = data.filter((r, idx) => newSelectedIds.has(r.id || idx));
    if (onSelectedRowsChange) {
      onSelectedRowsChange(Array.from(newSelectedIds) as any[], selectedRows);
    }
  };

  // 페이지 변경
  const handlePageChange = (page: number) => {
    if (page >= 1 && page <= totalPages) {
      setCurrentPage(page);
    }
  };

  // 디자인 모드 렌더링
  if (isDesignMode) {
    return (
      <div className={cn("rounded-lg border bg-muted/30 p-4", className)}>
        <div className="mb-2 text-xs font-medium text-muted-foreground">
          데이터 뷰: {targetTableName || "(테이블 미지정)"}
        </div>
        <Table>
          <TableHeader>
            <TableRow>
              {columns.length > 0 ? (
                columns.map((col) => (
                  <TableHead key={col.columnName}>
                    {col.columnLabel || col.columnName}
                  </TableHead>
                ))
              ) : (
                <>
                  <TableHead>컬럼 1</TableHead>
                  <TableHead>컬럼 2</TableHead>
                  <TableHead>컬럼 3</TableHead>
                </>
              )}
            </TableRow>
          </TableHeader>
          <TableBody>
            {[1, 2, 3].map((i) => (
              <TableRow key={i}>
                {columns.length > 0 ? (
                  columns.map((col) => (
                    <TableCell key={col.columnName}>
                      <div className="h-4 w-20 bg-muted-foreground/20 rounded" />
                    </TableCell>
                  ))
                ) : (
                  <>
                    <TableCell>
                      <div className="h-4 w-20 bg-muted-foreground/20 rounded" />
                    </TableCell>
                    <TableCell>
                      <div className="h-4 w-20 bg-muted-foreground/20 rounded" />
                    </TableCell>
                    <TableCell>
                      <div className="h-4 w-20 bg-muted-foreground/20 rounded" />
                    </TableCell>
                  </>
                )}
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </div>
    );
  }

  // 로딩 중
  if (loading && data.length === 0) {
    return (
      <div className={cn("rounded-lg border bg-card p-8 text-center", className)}>
        <Loader2 className="mx-auto h-8 w-8 animate-spin text-primary" />
        <p className="mt-2 text-sm text-muted-foreground">데이터를 불러오는 중...</p>
      </div>
    );
  }

  // 에러 표시
  if (error) {
    return (
      <div className={cn("rounded-lg border border-destructive/50 bg-destructive/10 p-4", className)}>
        <p className="text-sm text-destructive">⚠️ {error}</p>
        <Button variant="outline" size="sm" className="mt-2" onClick={loadData}>
          다시 시도
        </Button>
      </div>
    );
  }

  // 데이터 없음
  if (data.length === 0) {
    return (
      <div className={cn("rounded-lg border bg-card p-8 text-center", className)}>
        <p className="text-sm text-muted-foreground">표시할 데이터가 없습니다.</p>
      </div>
    );
  }

  // 테이블 렌더링
  return (
    <div className={cn("rounded-lg border bg-card", className)}>
      {/* 🔍 현재 적용된 필터 표시 */}
      {Object.keys(filters).length > 0 && (
        <div className="flex flex-wrap items-center gap-2 border-b bg-muted/50 px-4 py-2">
          <span className="text-xs font-medium text-muted-foreground">적용된 필터:</span>
          {Object.entries(filters).map(([key, value]) => (
            <div
              key={key}
              className="inline-flex items-center gap-1 rounded-md bg-primary/10 px-2 py-1 text-xs font-medium text-primary"
            >
              <span>{key}:</span>
              <span className="font-semibold">{String(value)}</span>
            </div>
          ))}
        </div>
      )}

      {/* 테이블 */}
      <div className="overflow-x-auto">
        <Table>
          <TableHeader>
            <TableRow>
              {columns.map((col) => (
                <TableHead
                  key={col.columnName}
                  className={cn("cursor-pointer select-none", {
                    "font-semibold": sortState.column === col.columnName,
                  })}
                  onClick={() => handleSort(col.columnName)}
                >
                  <div className="flex items-center gap-1">
                    <span>{col.columnLabel || col.columnName}</span>
                    {sortState.column === col.columnName && (
                      <>
                        {sortState.order === "asc" ? (
                          <ArrowUp className="h-3 w-3" />
                        ) : (
                          <ArrowDown className="h-3 w-3" />
                        )}
                      </>
                    )}
                  </div>
                </TableHead>
              ))}
            </TableRow>
          </TableHeader>
          <TableBody>
            {data.map((row, rowIndex) => {
              const rowId = row.id || rowIndex;
              const isSelected = selectedRowIds.has(rowId);

              return (
                <TableRow
                  key={rowId}
                  data-state={isSelected ? "selected" : undefined}
                  className={cn("cursor-pointer", {
                    "bg-primary/10": isSelected,
                  })}
                  onClick={() => handleRowClick(row, rowIndex)}
                >
                  {columns.map((col) => (
                    <TableCell key={col.columnName}>
                      {row[col.columnName] !== undefined && row[col.columnName] !== null
                        ? String(row[col.columnName])
                        : "-"}
                    </TableCell>
                  ))}
                </TableRow>
              );
            })}
          </TableBody>
        </Table>
      </div>

      {/* 페이징 */}
      {totalPages > 1 && (
        <div className="flex items-center justify-between border-t px-4 py-2">
          <div className="text-xs text-muted-foreground">
            전체 {totalCount}건 중 {(currentPage - 1) * pageSize + 1}~
            {Math.min(currentPage * pageSize, totalCount)}건
          </div>
          <div className="flex items-center gap-1">
            <Button
              variant="outline"
              size="sm"
              onClick={() => handlePageChange(currentPage - 1)}
              disabled={currentPage === 1 || loading}
              className="h-7 px-2 text-xs"
            >
              <ChevronLeft className="h-4 w-4" />
            </Button>
            <div className="flex items-center gap-1">
              {Array.from({ length: Math.min(5, totalPages) }, (_, i) => {
                const page = i + 1;
                return (
                  <Button
                    key={page}
                    variant={currentPage === page ? "default" : "ghost"}
                    size="sm"
                    onClick={() => handlePageChange(page)}
                    disabled={loading}
                    className="h-7 w-7 px-0 text-xs"
                  >
                    {page}
                  </Button>
                );
              })}
              {totalPages > 5 && <span className="text-xs text-muted-foreground">...</span>}
              {totalPages > 5 && (
                <Button
                  variant={currentPage === totalPages ? "default" : "ghost"}
                  size="sm"
                  onClick={() => handlePageChange(totalPages)}
                  disabled={loading}
                  className="h-7 w-7 px-0 text-xs"
                >
                  {totalPages}
                </Button>
              )}
            </div>
            <Button
              variant="outline"
              size="sm"
              onClick={() => handlePageChange(currentPage + 1)}
              disabled={currentPage === totalPages || loading}
              className="h-7 px-2 text-xs"
            >
              <ChevronRight className="h-4 w-4" />
            </Button>
          </div>
        </div>
      )}
    </div>
  );
}
