"use client";

import React, { useState, useEffect } from "react";
import { DashboardElement, QueryResult, ListWidgetConfig } from "../types";
import { Button } from "@/components/ui/button";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Card } from "@/components/ui/card";
import { getApiUrl } from "@/lib/utils/apiUrl";

interface ListWidgetProps {
  element: DashboardElement;
  onConfigUpdate?: (config: Partial<DashboardElement>) => void;
}

/**
 * 리스트 위젯 컴포넌트
 * - DB 쿼리 또는 REST API로 데이터 가져오기
 * - 테이블 형태로 데이터 표시
 * - 페이지네이션, 정렬, 검색 기능
 */
export function ListWidget({ element, onConfigUpdate }: ListWidgetProps) {
  const [data, setData] = useState<QueryResult | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [currentPage, setCurrentPage] = useState(1);

  const config = element.listConfig || {
    columnMode: "auto",
    viewMode: "table",
    columns: [],
    pageSize: 10,
    enablePagination: true,
    showHeader: true,
    stripedRows: true,
    compactMode: false,
    cardColumns: 3,
  };

  // 데이터 로드
  useEffect(() => {
    const loadData = async () => {
      if (!element.dataSource || (!element.dataSource.query && !element.dataSource.endpoint)) return;

      setIsLoading(true);
      setError(null);

      try {
        let queryResult: QueryResult;

        // REST API vs Database 분기
        if (element.dataSource.type === "api" && element.dataSource.endpoint) {
          // REST API - 백엔드 프록시를 통한 호출
          const params = new URLSearchParams();
          if (element.dataSource.queryParams) {
            Object.entries(element.dataSource.queryParams).forEach(([key, value]) => {
              if (key && value) {
                params.append(key, value);
              }
            });
          }

          const response = await fetch(getApiUrl("/api/dashboards/fetch-external-api"), {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify({
              url: element.dataSource.endpoint,
              method: "GET",
              headers: element.dataSource.headers || {},
              queryParams: Object.fromEntries(params),
            }),
          });

          if (!response.ok) {
            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
          }

          const result = await response.json();

          if (!result.success) {
            throw new Error(result.message || "외부 API 호출 실패");
          }

          const apiData = result.data;

          // JSON Path 처리
          let processedData = apiData;
          if (element.dataSource.jsonPath) {
            const paths = element.dataSource.jsonPath.split(".");
            for (const path of paths) {
              if (processedData && typeof processedData === "object" && path in processedData) {
                processedData = processedData[path];
              } else {
                throw new Error(`JSON Path "${element.dataSource.jsonPath}"에서 데이터를 찾을 수 없습니다`);
              }
            }
          }

          const rows = Array.isArray(processedData) ? processedData : [processedData];
          const columns = rows.length > 0 ? Object.keys(rows[0]) : [];

          queryResult = {
            columns,
            rows,
            totalRows: rows.length,
            executionTime: 0,
          };
        } else if (element.dataSource.query) {
          // Database (현재 DB 또는 외부 DB)
          if (element.dataSource.connectionType === "external" && element.dataSource.externalConnectionId) {
            // 외부 DB
            const { ExternalDbConnectionAPI } = await import("@/lib/api/externalDbConnection");
            const externalResult = await ExternalDbConnectionAPI.executeQuery(
              parseInt(element.dataSource.externalConnectionId),
              element.dataSource.query,
            );
            if (!externalResult.success) {
              throw new Error(externalResult.message || "외부 DB 쿼리 실행 실패");
            }
            queryResult = {
              columns: externalResult.data.columns,
              rows: externalResult.data.rows,
              totalRows: externalResult.data.rowCount,
              executionTime: 0,
            };
          } else {
            // 현재 DB
            const { dashboardApi } = await import("@/lib/api/dashboard");
            const result = await dashboardApi.executeQuery(element.dataSource.query);
            queryResult = {
              columns: result.columns,
              rows: result.rows,
              totalRows: result.rowCount,
              executionTime: 0,
            };
          }
        } else {
          throw new Error("데이터 소스가 올바르게 설정되지 않았습니다");
        }

        setData(queryResult);
      } catch (err) {
        setError(err instanceof Error ? err.message : "데이터 로딩 실패");
      } finally {
        setIsLoading(false);
      }
    };

    loadData();

    // 자동 새로고침 설정
    const refreshInterval = element.dataSource?.refreshInterval;
    if (refreshInterval && refreshInterval > 0) {
      const interval = setInterval(loadData, refreshInterval);
      return () => clearInterval(interval);
    }
  }, [
    element.dataSource?.query,
    element.dataSource?.connectionType,
    element.dataSource?.externalConnectionId,
    element.dataSource?.endpoint,
    element.dataSource?.refreshInterval,
  ]);

  // 로딩 중
  if (isLoading) {
    return (
      <div className="flex h-full w-full items-center justify-center">
        <div className="text-center">
          <div className="mx-auto mb-2 h-6 w-6 animate-spin rounded-full border-2 border-primary border-t-transparent" />
          <div className="text-sm text-foreground">데이터 로딩 중...</div>
        </div>
      </div>
    );
  }

  // 에러
  if (error) {
    return (
      <div className="flex h-full w-full items-center justify-center">
        <div className="text-center">
          <div className="mb-2 text-2xl">⚠️</div>
          <div className="text-sm font-medium text-destructive">오류 발생</div>
          <div className="mt-1 text-xs text-muted-foreground">{error}</div>
        </div>
      </div>
    );
  }

  // 데이터 없음
  if (!data) {
    return (
      <div className="flex h-full w-full flex-col items-center justify-center gap-4 p-4">
        <div className="text-center">
          <div className="mb-2 text-4xl">📋</div>
          <div className="text-sm font-medium text-foreground">리스트를 설정하세요</div>
          <div className="mt-1 text-xs text-muted-foreground">⚙️ 버튼을 클릭하여 데이터 소스와 컬럼을 설정해주세요</div>
        </div>
      </div>
    );
  }

  // 컬럼 설정이 없으면 자동으로 모든 컬럼 표시
  const displayColumns =
    config.columns.length > 0
      ? config.columns
      : data.columns.map((col) => ({
          id: col,
          name: col,
          dataKey: col,
          visible: true,
        }));

  // 페이지네이션
  const totalPages = Math.ceil(data.rows.length / config.pageSize);
  const startIdx = (currentPage - 1) * config.pageSize;
  const endIdx = startIdx + config.pageSize;
  const paginatedRows = config.enablePagination ? data.rows.slice(startIdx, endIdx) : data.rows;

  return (
    <div className="flex h-full w-full flex-col p-4">
      {/* 제목 - 항상 표시 */}
      <div className="mb-4">
        <h3 className="text-sm font-semibold text-foreground">{element.customTitle || element.title}</h3>
      </div>

      {/* 테이블 뷰 */}
      {config.viewMode === "table" && (
        <div className={`flex-1 overflow-auto rounded-lg border ${config.compactMode ? "text-xs" : "text-sm"}`}>
          <Table>
            {config.showHeader && (
              <TableHeader>
                <TableRow>
                  {displayColumns
                    .filter((col) => col.visible)
                    .map((col) => (
                      <TableHead
                        key={col.id}
                        className={col.align === "center" ? "text-center" : col.align === "right" ? "text-right" : ""}
                        style={{ width: col.width ? `${col.width}px` : undefined }}
                      >
                        {col.label || col.name}
                      </TableHead>
                    ))}
                </TableRow>
              </TableHeader>
            )}
            <TableBody>
              {paginatedRows.length === 0 ? (
                <TableRow>
                  <TableCell
                    colSpan={displayColumns.filter((col) => col.visible).length}
                    className="text-center text-muted-foreground"
                  >
                    데이터가 없습니다
                  </TableCell>
                </TableRow>
              ) : (
                paginatedRows.map((row, idx) => (
                  <TableRow key={idx} className={config.stripedRows ? undefined : ""}>
                    {displayColumns
                      .filter((col) => col.visible)
                      .map((col) => (
                        <TableCell
                          key={col.id}
                          className={col.align === "center" ? "text-center" : col.align === "right" ? "text-right" : ""}
                        >
                          {String(row[col.dataKey || col.field] ?? "")}
                        </TableCell>
                      ))}
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
        </div>
      )}

      {/* 카드 뷰 */}
      {config.viewMode === "card" && (
        <div className="flex-1 overflow-auto">
          {paginatedRows.length === 0 ? (
            <div className="flex h-full items-center justify-center text-muted-foreground">데이터가 없습니다</div>
          ) : (
            <div
              className={`grid gap-4 ${config.compactMode ? "text-xs" : "text-sm"}`}
              style={{
                gridTemplateColumns: `repeat(${config.cardColumns || 3}, minmax(0, 1fr))`,
              }}
            >
              {paginatedRows.map((row, idx) => (
                <Card key={idx} className="p-4 transition-shadow hover:shadow-md">
                  <div className="space-y-2">
                    {displayColumns
                      .filter((col) => col.visible)
                      .map((col) => (
                        <div key={col.id}>
                          <div className="text-xs font-medium text-muted-foreground">{col.label || col.name}</div>
                          <div
                            className={`font-medium text-foreground ${col.align === "center" ? "text-center" : col.align === "right" ? "text-right" : ""}`}
                          >
                            {String(row[col.dataKey || col.field] ?? "")}
                          </div>
                        </div>
                      ))}
                  </div>
                </Card>
              ))}
            </div>
          )}
        </div>
      )}

      {/* 페이지네이션 */}
      {config.enablePagination && totalPages > 1 && (
        <div className="mt-4 flex items-center justify-between text-sm">
          <div className="text-foreground">
            {startIdx + 1}-{Math.min(endIdx, data.rows.length)} / {data.rows.length}개
          </div>
          <div className="flex gap-2">
            <Button
              variant="outline"
              size="sm"
              onClick={() => setCurrentPage((p) => Math.max(1, p - 1))}
              disabled={currentPage === 1}
            >
              이전
            </Button>
            <div className="flex items-center gap-1 px-2">
              <span className="text-foreground">{currentPage}</span>
              <span className="text-muted-foreground">/</span>
              <span className="text-muted-foreground">{totalPages}</span>
            </div>
            <Button
              variant="outline"
              size="sm"
              onClick={() => setCurrentPage((p) => Math.min(totalPages, p + 1))}
              disabled={currentPage === totalPages}
            >
              다음
            </Button>
          </div>
        </div>
      )}
    </div>
  );
}
