"use client";

import React, { useState, useEffect, useMemo } from "react";
import { entityJoinApi } from "@/lib/api/entityJoin";
import { tableManagementApi } from "@/lib/api/tableManagement";
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Trash2, Database, ChevronsUpDown, Check } from "lucide-react";
import { cn } from "@/lib/utils";

interface CardDisplayConfigPanelProps {
  config: any;
  onChange: (config: any) => void;
  screenTableName?: string;
  tableColumns?: any[];
}

interface EntityJoinColumn {
  tableName: string;
  columnName: string;
  columnLabel: string;
  dataType: string;
  joinAlias: string;
  suggestedLabel: string;
}

interface JoinTable {
  tableName: string;
  currentDisplayColumn: string;
  joinConfig?: {
    sourceColumn: string;
  };
  availableColumns: Array<{
    columnName: string;
    columnLabel: string;
    dataType: string;
    description?: string;
  }>;
}

/**
 * CardDisplay 설정 패널
 * 카드 레이아웃과 동일한 설정 UI 제공 + 엔티티 조인 컬럼 지원
 */
export const CardDisplayConfigPanel: React.FC<CardDisplayConfigPanelProps> = ({
  config,
  onChange,
  screenTableName,
  tableColumns = [],
}) => {
  // 테이블 선택 상태
  const [tableComboboxOpen, setTableComboboxOpen] = useState(false);
  const [allTables, setAllTables] = useState<Array<{ tableName: string; displayName: string }>>([]);
  const [loadingTables, setLoadingTables] = useState(false);
  const [availableColumns, setAvailableColumns] = useState<any[]>([]);
  const [loadingColumns, setLoadingColumns] = useState(false);

  // 엔티티 조인 컬럼 상태
  const [entityJoinColumns, setEntityJoinColumns] = useState<{
    availableColumns: EntityJoinColumn[];
    joinTables: JoinTable[];
  }>({ availableColumns: [], joinTables: [] });
  const [loadingEntityJoins, setLoadingEntityJoins] = useState(false);

  // 현재 사용할 테이블명
  const targetTableName = useMemo(() => {
    if (config.useCustomTable && config.customTableName) {
      return config.customTableName;
    }
    return config.tableName || screenTableName;
  }, [config.useCustomTable, config.customTableName, config.tableName, screenTableName]);

  // 전체 테이블 목록 로드
  useEffect(() => {
    const loadAllTables = async () => {
      setLoadingTables(true);
      try {
        const response = await tableManagementApi.getTableList();
        if (response.success && response.data) {
          setAllTables(
            response.data.map((t: any) => ({
              tableName: t.tableName || t.table_name,
              displayName: t.tableLabel || t.displayName || t.tableName || t.table_name,
            })),
          );
        }
      } catch (error) {
        console.error("테이블 목록 로드 실패:", error);
      } finally {
        setLoadingTables(false);
      }
    };
    loadAllTables();
  }, []);

  // 선택된 테이블의 컬럼 로드
  useEffect(() => {
    const loadColumns = async () => {
      if (!targetTableName) {
        setAvailableColumns([]);
        return;
      }

      // 커스텀 테이블이 아니면 props로 받은 tableColumns 사용
      if (!config.useCustomTable && tableColumns && tableColumns.length > 0) {
        setAvailableColumns(tableColumns);
        return;
      }

      setLoadingColumns(true);
      try {
        const result = await tableManagementApi.getColumnList(targetTableName);
        if (result.success && result.data?.columns) {
          setAvailableColumns(
            result.data.columns.map((col: any) => ({
              columnName: col.columnName,
              columnLabel: col.displayName || col.columnLabel || col.columnName,
              dataType: col.dataType,
            })),
          );
        }
      } catch (error) {
        console.error("컬럼 목록 로드 실패:", error);
        setAvailableColumns([]);
      } finally {
        setLoadingColumns(false);
      }
    };
    loadColumns();
  }, [targetTableName, config.useCustomTable, tableColumns]);

  // 엔티티 조인 컬럼 정보 가져오기
  useEffect(() => {
    const fetchEntityJoinColumns = async () => {
      if (!targetTableName) {
        setEntityJoinColumns({ availableColumns: [], joinTables: [] });
        return;
      }

      setLoadingEntityJoins(true);
      try {
        const result = await entityJoinApi.getEntityJoinColumns(targetTableName);
        setEntityJoinColumns({
          availableColumns: result.availableColumns || [],
          joinTables: result.joinTables || [],
        });
      } catch (error) {
        console.error("Entity 조인 컬럼 조회 오류:", error);
        setEntityJoinColumns({ availableColumns: [], joinTables: [] });
      } finally {
        setLoadingEntityJoins(false);
      }
    };

    fetchEntityJoinColumns();
  }, [targetTableName]);

  // 테이블 선택 핸들러
  const handleTableSelect = (tableName: string, isScreenTable: boolean) => {
    if (isScreenTable) {
      // 화면 기본 테이블 선택
      onChange({
        ...config,
        useCustomTable: false,
        customTableName: undefined,
        tableName: tableName,
        columnMapping: { displayColumns: [] }, // 컬럼 매핑 초기화
      });
    } else {
      // 다른 테이블 선택
      onChange({
        ...config,
        useCustomTable: true,
        customTableName: tableName,
        tableName: tableName,
        columnMapping: { displayColumns: [] }, // 컬럼 매핑 초기화
      });
    }
    setTableComboboxOpen(false);
  };

  // 현재 선택된 테이블 표시명 가져오기
  const getSelectedTableDisplay = () => {
    if (!targetTableName) return "테이블을 선택하세요";
    const found = allTables.find((t) => t.tableName === targetTableName);
    return found?.displayName || targetTableName;
  };

  const handleChange = (key: string, value: any) => {
    onChange({ ...config, [key]: value });
  };

  const handleNestedChange = (path: string, value: any) => {
    const keys = path.split(".");
    let newConfig = { ...config };
    let current = newConfig;

    for (let i = 0; i < keys.length - 1; i++) {
      if (!current[keys[i]]) {
        current[keys[i]] = {};
      }
      current = current[keys[i]];
    }

    current[keys[keys.length - 1]] = value;
    onChange(newConfig);
  };

  // 컬럼 선택 시 조인 컬럼이면 joinColumns 설정도 함께 업데이트
  const handleColumnSelect = (path: string, columnName: string) => {
    const joinColumn = entityJoinColumns.availableColumns.find((col) => col.joinAlias === columnName);

    if (joinColumn) {
      const joinColumnsConfig = config.joinColumns || [];
      const existingJoinColumn = joinColumnsConfig.find((jc: any) => jc.columnName === columnName);

      if (!existingJoinColumn) {
        const joinTableInfo = entityJoinColumns.joinTables?.find((jt) => jt.tableName === joinColumn.tableName);

        const newJoinColumnConfig = {
          columnName: joinColumn.joinAlias,
          label: joinColumn.suggestedLabel || joinColumn.columnLabel,
          sourceColumn: joinTableInfo?.joinConfig?.sourceColumn || "",
          referenceTable: joinColumn.tableName,
          referenceColumn: joinColumn.columnName,
          isJoinColumn: true,
        };

        onChange({
          ...config,
          columnMapping: {
            ...config.columnMapping,
            [path.split(".")[1]]: columnName,
          },
          joinColumns: [...joinColumnsConfig, newJoinColumnConfig],
        });
        return;
      }
    }

    handleNestedChange(path, columnName);
  };

  // 표시 컬럼 추가
  const addDisplayColumn = () => {
    const currentColumns = config.columnMapping?.displayColumns || [];
    const newColumns = [...currentColumns, ""];
    handleNestedChange("columnMapping.displayColumns", newColumns);
  };

  // 표시 컬럼 삭제
  const removeDisplayColumn = (index: number) => {
    const currentColumns = [...(config.columnMapping?.displayColumns || [])];
    currentColumns.splice(index, 1);
    handleNestedChange("columnMapping.displayColumns", currentColumns);
  };

  // 표시 컬럼 값 변경
  const updateDisplayColumn = (index: number, value: string) => {
    const currentColumns = [...(config.columnMapping?.displayColumns || [])];
    currentColumns[index] = value;

    const joinColumn = entityJoinColumns.availableColumns.find((col) => col.joinAlias === value);

    if (joinColumn) {
      const joinColumnsConfig = config.joinColumns || [];
      const existingJoinColumn = joinColumnsConfig.find((jc: any) => jc.columnName === value);

      if (!existingJoinColumn) {
        const joinTableInfo = entityJoinColumns.joinTables?.find((jt) => jt.tableName === joinColumn.tableName);

        const newJoinColumnConfig = {
          columnName: joinColumn.joinAlias,
          label: joinColumn.suggestedLabel || joinColumn.columnLabel,
          sourceColumn: joinTableInfo?.joinConfig?.sourceColumn || "",
          referenceTable: joinColumn.tableName,
          referenceColumn: joinColumn.columnName,
          isJoinColumn: true,
        };

        onChange({
          ...config,
          columnMapping: {
            ...config.columnMapping,
            displayColumns: currentColumns,
          },
          joinColumns: [...joinColumnsConfig, newJoinColumnConfig],
        });
        return;
      }
    }

    handleNestedChange("columnMapping.displayColumns", currentColumns);
  };

  // 테이블별로 조인 컬럼 그룹화
  const joinColumnsByTable: Record<string, EntityJoinColumn[]> = {};
  entityJoinColumns.availableColumns.forEach((col) => {
    if (!joinColumnsByTable[col.tableName]) {
      joinColumnsByTable[col.tableName] = [];
    }
    joinColumnsByTable[col.tableName].push(col);
  });

  // 현재 사용할 컬럼 목록 (커스텀 테이블이면 로드한 컬럼, 아니면 props)
  const currentTableColumns = config.useCustomTable
    ? availableColumns
    : tableColumns.length > 0
      ? tableColumns
      : availableColumns;

  // 컬럼 선택 셀렉트 박스 렌더링 (Shadcn UI)
  const renderColumnSelect = (
    value: string,
    onChangeHandler: (value: string) => void,
    placeholder: string = "컬럼을 선택하세요",
  ) => {
    return (
      <Select value={value || "__none__"} onValueChange={(val) => onChangeHandler(val === "__none__" ? "" : val)}>
        <SelectTrigger className="h-8 text-xs">
          <SelectValue placeholder={placeholder} />
        </SelectTrigger>
        <SelectContent>
          {/* 선택 안함 옵션 */}
          <SelectItem value="__none__" className="text-muted-foreground text-xs">
            선택 안함
          </SelectItem>

          {/* 기본 테이블 컬럼 */}
          {currentTableColumns.length > 0 && (
            <SelectGroup>
              <SelectLabel className="text-muted-foreground text-xs font-semibold">기본 컬럼</SelectLabel>
              {currentTableColumns.map((column: any) => (
                <SelectItem key={column.columnName} value={column.columnName} className="text-xs">
                  {column.columnLabel || column.columnName}
                </SelectItem>
              ))}
            </SelectGroup>
          )}

          {/* 조인 테이블별 컬럼 */}
          {Object.entries(joinColumnsByTable).map(([tableName, columns]) => (
            <SelectGroup key={tableName}>
              <SelectLabel className="text-xs font-semibold text-blue-600">{tableName} (조인)</SelectLabel>
              {columns.map((col) => (
                <SelectItem key={col.joinAlias} value={col.joinAlias} className="text-xs">
                  {col.suggestedLabel || col.columnLabel}
                </SelectItem>
              ))}
            </SelectGroup>
          ))}
        </SelectContent>
      </Select>
    );
  };

  return (
    <div className="space-y-4">
      <div className="text-sm font-medium">카드 디스플레이 설정</div>

      {/* 테이블 선택 */}
      <div className="space-y-2">
        <Label className="text-xs font-medium">표시 테이블</Label>
        <Popover open={tableComboboxOpen} onOpenChange={setTableComboboxOpen}>
          <PopoverTrigger asChild>
            <Button
              variant="outline"
              role="combobox"
              aria-expanded={tableComboboxOpen}
              className="h-9 w-full justify-between text-xs"
              disabled={loadingTables}
            >
              <div className="flex items-center gap-2 truncate">
                <Database className="text-muted-foreground h-3.5 w-3.5 shrink-0" />
                <span className="truncate">{getSelectedTableDisplay()}</span>
              </div>
              <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
            </Button>
          </PopoverTrigger>
          <PopoverContent className="w-[300px] p-0" align="start">
            <Command>
              <CommandInput placeholder="테이블 검색..." className="text-xs" />
              <CommandList>
                <CommandEmpty className="text-muted-foreground py-3 text-center text-xs">
                  테이블을 찾을 수 없습니다.
                </CommandEmpty>

                {/* 화면 기본 테이블 */}
                {screenTableName && (
                  <CommandGroup heading="기본 (화면 테이블)">
                    <CommandItem
                      value={screenTableName}
                      onSelect={() => handleTableSelect(screenTableName, true)}
                      className="text-xs"
                    >
                      <Check
                        className={cn(
                          "mr-2 h-4 w-4",
                          targetTableName === screenTableName && !config.useCustomTable ? "opacity-100" : "opacity-0",
                        )}
                      />
                      <Database className="mr-2 h-3.5 w-3.5 text-blue-500" />
                      {allTables.find((t) => t.tableName === screenTableName)?.displayName || screenTableName}
                    </CommandItem>
                  </CommandGroup>
                )}

                {/* 전체 테이블 */}
                <CommandGroup heading="전체 테이블">
                  {allTables
                    .filter((t) => t.tableName !== screenTableName)
                    .map((table) => (
                      <CommandItem
                        key={table.tableName}
                        value={table.tableName}
                        onSelect={() => handleTableSelect(table.tableName, false)}
                        className="text-xs"
                      >
                        <Check
                          className={cn(
                            "mr-2 h-4 w-4",
                            config.useCustomTable && targetTableName === table.tableName ? "opacity-100" : "opacity-0",
                          )}
                        />
                        <Database className="text-muted-foreground mr-2 h-3.5 w-3.5" />
                        <span className="truncate">{table.displayName}</span>
                      </CommandItem>
                    ))}
                </CommandGroup>
              </CommandList>
            </Command>
          </PopoverContent>
        </Popover>
        {config.useCustomTable && (
          <p className="text-muted-foreground text-[10px]">
            화면 기본 테이블이 아닌 다른 테이블의 데이터를 표시합니다.
          </p>
        )}
      </div>

      {/* 테이블이 선택된 경우 컬럼 매핑 설정 */}
      {(currentTableColumns.length > 0 || loadingColumns) && (
        <div className="space-y-3">
          <h5 className="text-muted-foreground text-xs font-medium">컬럼 매핑</h5>

          {(loadingEntityJoins || loadingColumns) && (
            <div className="text-muted-foreground text-xs">
              {loadingColumns ? "컬럼 로딩 중..." : "조인 컬럼 로딩 중..."}
            </div>
          )}

          <div className="space-y-1">
            <Label className="text-xs">타이틀 컬럼</Label>
            {renderColumnSelect(config.columnMapping?.titleColumn || "", (value) =>
              handleColumnSelect("columnMapping.titleColumn", value),
            )}
          </div>

          <div className="space-y-1">
            <Label className="text-xs">서브타이틀 컬럼</Label>
            {renderColumnSelect(config.columnMapping?.subtitleColumn || "", (value) =>
              handleColumnSelect("columnMapping.subtitleColumn", value),
            )}
          </div>

          <div className="space-y-1">
            <Label className="text-xs">설명 컬럼</Label>
            {renderColumnSelect(config.columnMapping?.descriptionColumn || "", (value) =>
              handleColumnSelect("columnMapping.descriptionColumn", value),
            )}
          </div>

          <div className="space-y-1">
            <Label className="text-xs">이미지 컬럼</Label>
            {renderColumnSelect(config.columnMapping?.imageColumn || "", (value) =>
              handleColumnSelect("columnMapping.imageColumn", value),
            )}
          </div>

          {/* 동적 표시 컬럼 추가 */}
          <div className="space-y-2">
            <div className="flex items-center justify-between">
              <Label className="text-xs">표시 컬럼들</Label>
              <Button type="button" variant="outline" size="sm" onClick={addDisplayColumn} className="h-6 px-2 text-xs">
                + 컬럼 추가
              </Button>
            </div>

            <div className="space-y-2">
              {(config.columnMapping?.displayColumns || []).map((column: string, index: number) => (
                <div key={index} className="flex items-center gap-2">
                  <div className="flex-1">
                    {renderColumnSelect(column, (value) => updateDisplayColumn(index, value))}
                  </div>
                  <Button
                    type="button"
                    variant="ghost"
                    size="sm"
                    onClick={() => removeDisplayColumn(index)}
                    className="text-destructive hover:bg-destructive/10 hover:text-destructive h-8 w-8 p-0"
                  >
                    <Trash2 className="h-4 w-4" />
                  </Button>
                </div>
              ))}

              {(!config.columnMapping?.displayColumns || config.columnMapping.displayColumns.length === 0) && (
                <div className="border-muted-foreground/30 text-muted-foreground rounded-md border border-dashed py-3 text-center text-xs">
                  "컬럼 추가" 버튼을 클릭하여 표시할 컬럼을 추가하세요
                </div>
              )}
            </div>
          </div>
        </div>
      )}

      {/* 카드 스타일 설정 */}
      <div className="space-y-3">
        <h5 className="text-muted-foreground text-xs font-medium">카드 스타일</h5>

        <div className="grid grid-cols-2 gap-3">
          <div className="space-y-1">
            <Label className="text-xs">한 행당 카드 수</Label>
            <Input
              type="number"
              min="1"
              max="6"
              value={config.cardsPerRow || 3}
              onChange={(e) => handleChange("cardsPerRow", parseInt(e.target.value))}
              className="h-8 text-xs"
            />
          </div>

          <div className="space-y-1">
            <Label className="text-xs">카드 간격 (px)</Label>
            <Input
              type="number"
              min="0"
              max="50"
              value={config.cardSpacing || 16}
              onChange={(e) => handleChange("cardSpacing", parseInt(e.target.value))}
              className="h-8 text-xs"
            />
          </div>
        </div>

        <div className="space-y-2">
          <div className="flex items-center space-x-2">
            <Checkbox
              id="showTitle"
              checked={config.cardStyle?.showTitle ?? true}
              onCheckedChange={(checked) => handleNestedChange("cardStyle.showTitle", checked)}
            />
            <Label htmlFor="showTitle" className="text-xs font-normal">
              타이틀 표시
            </Label>
          </div>

          <div className="flex items-center space-x-2">
            <Checkbox
              id="showSubtitle"
              checked={config.cardStyle?.showSubtitle ?? true}
              onCheckedChange={(checked) => handleNestedChange("cardStyle.showSubtitle", checked)}
            />
            <Label htmlFor="showSubtitle" className="text-xs font-normal">
              서브타이틀 표시
            </Label>
          </div>

          <div className="flex items-center space-x-2">
            <Checkbox
              id="showDescription"
              checked={config.cardStyle?.showDescription ?? true}
              onCheckedChange={(checked) => handleNestedChange("cardStyle.showDescription", checked)}
            />
            <Label htmlFor="showDescription" className="text-xs font-normal">
              설명 표시
            </Label>
          </div>

          <div className="flex items-center space-x-2">
            <Checkbox
              id="showImage"
              checked={config.cardStyle?.showImage ?? false}
              onCheckedChange={(checked) => handleNestedChange("cardStyle.showImage", checked)}
            />
            <Label htmlFor="showImage" className="text-xs font-normal">
              이미지 표시
            </Label>
          </div>

          <div className="flex items-center space-x-2">
            <Checkbox
              id="showActions"
              checked={config.cardStyle?.showActions ?? true}
              onCheckedChange={(checked) => handleNestedChange("cardStyle.showActions", checked)}
            />
            <Label htmlFor="showActions" className="text-xs font-normal">
              액션 버튼 표시
            </Label>
          </div>

          {/* 개별 버튼 설정 */}
          {(config.cardStyle?.showActions ?? true) && (
            <div className="border-muted ml-5 space-y-2 border-l-2 pl-3">
              <div className="flex items-center space-x-2">
                <Checkbox
                  id="showViewButton"
                  checked={config.cardStyle?.showViewButton ?? true}
                  onCheckedChange={(checked) => handleNestedChange("cardStyle.showViewButton", checked)}
                />
                <Label htmlFor="showViewButton" className="text-xs font-normal">
                  상세보기 버튼
                </Label>
              </div>

              <div className="flex items-center space-x-2">
                <Checkbox
                  id="showEditButton"
                  checked={config.cardStyle?.showEditButton ?? true}
                  onCheckedChange={(checked) => handleNestedChange("cardStyle.showEditButton", checked)}
                />
                <Label htmlFor="showEditButton" className="text-xs font-normal">
                  편집 버튼
                </Label>
              </div>

              <div className="flex items-center space-x-2">
                <Checkbox
                  id="showDeleteButton"
                  checked={config.cardStyle?.showDeleteButton ?? false}
                  onCheckedChange={(checked) => handleNestedChange("cardStyle.showDeleteButton", checked)}
                />
                <Label htmlFor="showDeleteButton" className="text-xs font-normal">
                  삭제 버튼
                </Label>
              </div>
            </div>
          )}
        </div>

        <div className="space-y-1">
          <Label className="text-xs">설명 최대 길이</Label>
          <Input
            type="number"
            min="10"
            max="500"
            value={config.cardStyle?.maxDescriptionLength || 100}
            onChange={(e) => handleNestedChange("cardStyle.maxDescriptionLength", parseInt(e.target.value))}
            className="h-8 text-xs"
          />
        </div>
      </div>

      {/* 공통 설정 */}
      <div className="space-y-3">
        <h5 className="text-muted-foreground text-xs font-medium">공통 설정</h5>

        <div className="flex items-center space-x-2">
          <Checkbox
            id="disabled"
            checked={config.disabled || false}
            onCheckedChange={(checked) => handleChange("disabled", checked)}
          />
          <Label htmlFor="disabled" className="text-xs font-normal">
            비활성화
          </Label>
        </div>

        <div className="flex items-center space-x-2">
          <Checkbox
            id="readonly"
            checked={config.readonly || false}
            onCheckedChange={(checked) => handleChange("readonly", checked)}
          />
          <Label htmlFor="readonly" className="text-xs font-normal">
            읽기 전용
          </Label>
        </div>
      </div>
    </div>
  );
};
