"use client";

import React, { useState, useEffect, useMemo } from "react";
import { Badge } from "@/components/ui/badge";
import { Progress } from "@/components/ui/progress";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { ColumnInfo } from "@/lib/api/dataflow";
import { DataSaveSettings } from "@/types/connectionTypes";
import { ColumnTableSection } from "./ColumnTableSection";
import {
  getColumnsFromConnection,
  getTablesFromConnection,
  ColumnInfo as MultiColumnInfo,
} from "@/lib/api/multiConnection";

interface InsertFieldMappingPanelProps {
  action: DataSaveSettings["actions"][0];
  actionIndex: number;
  settings: DataSaveSettings;
  onSettingsChange: (settings: DataSaveSettings) => void;
  fromTableColumns?: ColumnInfo[];
  toTableColumns?: ColumnInfo[];
  fromTableName?: string;
  toTableName?: string;
  // 다중 커넥션 지원
  fromConnectionId?: number;
  toConnectionId?: number;
}

interface ColumnMapping {
  toColumnName: string;
  fromColumnName?: string;
  defaultValue?: string;
}

export const InsertFieldMappingPanel: React.FC<InsertFieldMappingPanelProps> = ({
  action,
  actionIndex,
  settings,
  onSettingsChange,
  fromTableColumns = [],
  toTableColumns = [],
  fromTableName,
  toTableName,
  fromConnectionId,
  toConnectionId,
}) => {
  const [selectedFromColumn, setSelectedFromColumn] = useState<string | null>(null);
  const [selectedToColumn, setSelectedToColumn] = useState<string | null>(null);
  const [columnMappings, setColumnMappings] = useState<ColumnMapping[]>([]);

  // 다중 커넥션에서 로드한 컬럼 정보
  const [multiFromColumns, setMultiFromColumns] = useState<MultiColumnInfo[]>([]);
  const [multiToColumns, setMultiToColumns] = useState<MultiColumnInfo[]>([]);
  const [isLoadingColumns, setIsLoadingColumns] = useState(false);

  // 테이블 라벨명 정보
  const [fromTableDisplayName, setFromTableDisplayName] = useState<string>("");
  const [toTableDisplayName, setToTableDisplayName] = useState<string>("");

  // 검색 및 필터링 상태 (FROM과 TO 독립적)
  const [fromSearchTerm, setFromSearchTerm] = useState("");
  const [toSearchTerm, setToSearchTerm] = useState("");
  const [fromDataTypeFilter, setFromDataTypeFilter] = useState("");
  const [toDataTypeFilter, setToDataTypeFilter] = useState("");

  // FROM 테이블 필터
  const [fromShowMappedOnly, setFromShowMappedOnly] = useState(false);
  const [fromShowUnmappedOnly, setFromShowUnmappedOnly] = useState(false);

  // TO 테이블 필터
  const [toShowMappedOnly, setToShowMappedOnly] = useState(false);
  const [toShowUnmappedOnly, setToShowUnmappedOnly] = useState(false);

  // 다중 커넥션에서 컬럼 정보 및 테이블 라벨명 로드
  useEffect(() => {
    const loadColumnsAndTableInfo = async () => {
      if (fromConnectionId !== undefined && toConnectionId !== undefined && fromTableName && toTableName) {
        setIsLoadingColumns(true);
        try {
          const [fromCols, toCols, fromTables, toTables] = await Promise.all([
            getColumnsFromConnection(fromConnectionId, fromTableName),
            getColumnsFromConnection(toConnectionId, toTableName),
            getTablesFromConnection(fromConnectionId),
            getTablesFromConnection(toConnectionId),
          ]);

          setMultiFromColumns(fromCols);
          setMultiToColumns(toCols);

          // 테이블 라벨명 설정
          const fromTable = fromTables.find((t) => t.tableName === fromTableName);
          const toTable = toTables.find((t) => t.tableName === toTableName);

          setFromTableDisplayName(
            fromTable?.displayName && fromTable.displayName !== fromTable.tableName
              ? fromTable.displayName
              : fromTableName,
          );

          setToTableDisplayName(
            toTable?.displayName && toTable.displayName !== toTable.tableName ? toTable.displayName : toTableName,
          );
        } catch (error) {
          console.error("컬럼 정보 및 테이블 정보 로드 실패:", error);
        } finally {
          setIsLoadingColumns(false);
        }
      }
    };

    loadColumnsAndTableInfo();
  }, [fromConnectionId, toConnectionId, fromTableName, toTableName]);

  // 사용할 컬럼 데이터 결정 (다중 커넥션 > 기존)
  const actualFromColumns = useMemo(() => {
    if (multiFromColumns.length > 0) {
      return multiFromColumns.map((col) => ({
        columnName: col.columnName,
        displayName: col.displayName,
        dataType: col.dataType,
        isNullable: col.isNullable,
        isPrimaryKey: col.isPrimaryKey,
        defaultValue: col.defaultValue,
        maxLength: col.maxLength,
        description: col.description,
      }));
    }
    return fromTableColumns || [];
  }, [multiFromColumns.length, fromTableColumns?.length]);

  const actualToColumns = useMemo(() => {
    if (multiToColumns.length > 0) {
      return multiToColumns.map((col) => ({
        columnName: col.columnName,
        displayName: col.displayName,
        dataType: col.dataType,
        isNullable: col.isNullable,
        isPrimaryKey: col.isPrimaryKey,
        defaultValue: col.defaultValue,
        maxLength: col.maxLength,
        description: col.description,
      }));
    }
    return toTableColumns || [];
  }, [multiToColumns.length, toTableColumns?.length]);

  // 기존 매핑 데이터를 columnMappings로 변환
  useEffect(() => {
    const columnsToUse = multiToColumns.length > 0 ? multiToColumns : toTableColumns || [];

    const mappings: ColumnMapping[] = columnsToUse.map((toCol) => {
      const existingMapping = action.fieldMappings.find((mapping) => mapping.targetField === toCol.columnName);

      return {
        toColumnName: toCol.columnName,
        fromColumnName: existingMapping?.sourceField || undefined,
        defaultValue: existingMapping?.defaultValue || "",
      };
    });

    setColumnMappings(mappings);
  }, [action.fieldMappings, multiToColumns.length, toTableColumns?.length]);

  // columnMappings 변경 시 settings 업데이트
  const updateSettings = (newMappings: ColumnMapping[]) => {
    const newActions = [...settings.actions];

    // 새로운 fieldMappings 생성
    const fieldMappings = newMappings
      .filter((mapping) => mapping.fromColumnName || (mapping.defaultValue && mapping.defaultValue.trim()))
      .map((mapping) => ({
        sourceTable: mapping.fromColumnName ? fromTableName || "" : "",
        sourceField: mapping.fromColumnName || "",
        targetTable: toTableName || "",
        targetField: mapping.toColumnName,
        defaultValue: mapping.defaultValue || "",
        transformFunction: "",
      }));

    newActions[actionIndex].fieldMappings = fieldMappings;
    onSettingsChange({ ...settings, actions: newActions });
  };

  // FROM 컬럼 클릭 핸들러
  const handleFromColumnClick = (columnName: string) => {
    if (selectedFromColumn === columnName) {
      setSelectedFromColumn(null);
    } else {
      setSelectedFromColumn(columnName);

      // TO 컬럼이 이미 선택되어 있으면 매핑 시도
      if (selectedToColumn) {
        const fromColumn = fromTableColumns.find((col) => col.columnName === columnName);
        const toColumn = toTableColumns.find((col) => col.columnName === selectedToColumn);

        if (fromColumn && toColumn) {
          // 데이터 타입 호환성 체크
          if (fromColumn.dataType !== toColumn.dataType) {
            alert(`데이터 타입이 다릅니다. FROM: ${fromColumn.dataType}, TO: ${toColumn.dataType}`);
            return;
          }

          // 매핑 생성
          createMapping(columnName, selectedToColumn);
          setSelectedFromColumn(null);
          setSelectedToColumn(null);
        }
      }
    }
  };

  // 공통 매핑 생성 함수
  const createMapping = (fromColumnName: string, toColumnName: string) => {
    const newMappings = columnMappings.map((mapping) => {
      if (mapping.toColumnName === toColumnName) {
        return {
          ...mapping,
          fromColumnName: fromColumnName,
          defaultValue: "", // 매핑이 설정되면 기본값 초기화
        };
      }
      return mapping;
    });

    setColumnMappings(newMappings);
    updateSettings(newMappings);
  };

  // TO 컬럼 클릭 핸들러
  const handleToColumnClick = (toColumnName: string) => {
    const currentMapping = columnMappings.find((m) => m.toColumnName === toColumnName);

    // 이미 매핑된 컬럼인 경우 처리하지 않음
    if (currentMapping?.fromColumnName) return;

    if (selectedToColumn === toColumnName) {
      setSelectedToColumn(null);
    } else {
      setSelectedToColumn(toColumnName);

      // FROM 컬럼이 이미 선택되어 있으면 매핑 시도
      if (selectedFromColumn) {
        const fromColumn = fromTableColumns.find((col) => col.columnName === selectedFromColumn);
        const toColumn = toTableColumns.find((col) => col.columnName === toColumnName);

        if (fromColumn && toColumn) {
          // 데이터 타입 호환성 체크
          if (fromColumn.dataType !== toColumn.dataType) {
            alert(`데이터 타입이 다릅니다. FROM: ${fromColumn.dataType}, TO: ${toColumn.dataType}`);
            return;
          }

          // 매핑 생성
          createMapping(selectedFromColumn, toColumnName);
          setSelectedFromColumn(null);
          setSelectedToColumn(null);
        }
      }
    }
  };

  // 기본값 변경 핸들러
  const handleDefaultValueChange = (toColumnName: string, value: string) => {
    const newMappings = columnMappings.map((mapping) => {
      if (mapping.toColumnName === toColumnName) {
        return {
          ...mapping,
          fromColumnName: value.trim() ? undefined : mapping.fromColumnName, // 기본값이 있으면 매핑 제거
          defaultValue: value,
        };
      }
      return mapping;
    });

    setColumnMappings(newMappings);
    updateSettings(newMappings);
  };

  // 매핑 제거 핸들러
  const handleRemoveMapping = (toColumnName: string) => {
    const newMappings = columnMappings.map((mapping) => {
      if (mapping.toColumnName === toColumnName) {
        return {
          ...mapping,
          fromColumnName: undefined,
          defaultValue: "",
        };
      }
      return mapping;
    });

    setColumnMappings(newMappings);
    updateSettings(newMappings);
  };

  // FROM 컬럼이 클릭 가능한지 확인 (데이터 타입 호환성 + 1대1 매핑 제약)
  const isFromColumnClickable = (fromColumn: ColumnInfo) => {
    // 이미 다른 TO 컬럼과 매핑된 FROM 컬럼은 클릭 불가
    const isAlreadyMapped = columnMappings.some((mapping) => mapping.fromColumnName === fromColumn.columnName);
    if (isAlreadyMapped) return false;

    if (!selectedToColumn) return true; // TO가 선택되지 않았으면 모든 FROM 클릭 가능

    const toColumn = actualToColumns.find((col) => col.columnName === selectedToColumn);
    if (!toColumn) return true;

    return fromColumn.dataType === toColumn.dataType;
  };

  // TO 컬럼이 클릭 가능한지 확인 (데이터 타입 호환성)
  const isToColumnClickable = (toColumn: ColumnInfo) => {
    const currentMapping = columnMappings.find((m) => m.toColumnName === toColumn.columnName);

    // 이미 매핑된 컬럼은 클릭 불가
    if (currentMapping?.fromColumnName) return false;

    // 기본값이 설정된 컬럼은 클릭 불가
    if (currentMapping?.defaultValue && currentMapping.defaultValue.trim()) return false;

    if (!selectedFromColumn) return true; // FROM이 선택되지 않았으면 모든 TO 클릭 가능

    const fromColumn = actualFromColumns.find((col) => col.columnName === selectedFromColumn);
    if (!fromColumn) return true;

    return fromColumn.dataType === toColumn.dataType;
  };

  return (
    <div className="mt-4">
      {/* 헤더 섹션 */}
      <p className="mb-4 text-sm leading-relaxed text-foreground">
        양쪽 테이블의 컬럼을 클릭하여 매핑하거나, 대상 컬럼에 기본값을 입력하세요. 같은 데이터 타입의 컬럼만 매핑
        가능합니다. 하나의 FROM 컬럼은 하나의 TO 컬럼에만 매핑 가능합니다.
      </p>

      <div className="grid grid-cols-2 gap-6">
        <ColumnTableSection
          type="from"
          tableName={fromTableDisplayName || fromTableName || "소스 테이블"}
          columns={actualFromColumns}
          selectedColumn={selectedFromColumn}
          onColumnClick={handleFromColumnClick}
          searchTerm={fromSearchTerm}
          onSearchChange={setFromSearchTerm}
          dataTypeFilter={fromDataTypeFilter}
          onDataTypeFilterChange={setFromDataTypeFilter}
          showMappedOnly={fromShowMappedOnly}
          onShowMappedOnlyChange={setFromShowMappedOnly}
          showUnmappedOnly={fromShowUnmappedOnly}
          onShowUnmappedOnlyChange={setFromShowUnmappedOnly}
          columnMappings={columnMappings}
          isColumnClickable={isFromColumnClickable}
          oppositeSelectedColumn={selectedToColumn}
          oppositeColumns={actualToColumns}
        />

        <ColumnTableSection
          type="to"
          tableName={toTableDisplayName || toTableName || "대상 테이블"}
          columns={actualToColumns}
          selectedColumn={selectedToColumn}
          onColumnClick={handleToColumnClick}
          searchTerm={toSearchTerm}
          onSearchChange={setToSearchTerm}
          dataTypeFilter={toDataTypeFilter}
          onDataTypeFilterChange={setToDataTypeFilter}
          showMappedOnly={toShowMappedOnly}
          onShowMappedOnlyChange={setToShowMappedOnly}
          showUnmappedOnly={toShowUnmappedOnly}
          onShowUnmappedOnlyChange={setToShowUnmappedOnly}
          columnMappings={columnMappings}
          onDefaultValueChange={handleDefaultValueChange}
          onRemoveMapping={handleRemoveMapping}
          isColumnClickable={isToColumnClickable}
          oppositeSelectedColumn={selectedFromColumn}
          oppositeColumns={actualFromColumns}
        />
      </div>

      {/* 빠른 필터 액션 */}
      <Card className="mt-6 border-none py-2 shadow-none">
        <CardContent className="flex flex-wrap gap-2 p-3">
          <span className="self-center text-sm font-medium text-foreground">빠른 필터:</span>
          <Button
            variant="secondary"
            size="sm"
            onClick={() => {
              setFromSearchTerm("");
              setToSearchTerm("");
              setFromDataTypeFilter("");
              setToDataTypeFilter("");
              setFromShowMappedOnly(false);
              setFromShowUnmappedOnly(false);
              setToShowMappedOnly(false);
              setToShowUnmappedOnly(false);
            }}
            className="h-7 text-xs"
          >
            전체 보기
          </Button>
          <Button
            variant="outline"
            size="sm"
            onClick={() => {
              // FROM: 미매핑만, TO: 미설정만
              setFromShowMappedOnly(false);
              setFromShowUnmappedOnly(true);
              setToShowMappedOnly(false);
              setToShowUnmappedOnly(true);
            }}
            className="h-7 text-xs"
          >
            미매핑만 보기
          </Button>
          <Button
            variant="outline"
            size="sm"
            onClick={() => {
              // FROM: 매핑됨만, TO: 설정됨만
              setFromShowMappedOnly(true);
              setFromShowUnmappedOnly(false);
              setToShowMappedOnly(true);
              setToShowUnmappedOnly(false);
            }}
            className="h-7 text-xs"
          >
            매핑됨만 보기
          </Button>
          <div className="ml-auto flex gap-2">
            <Badge variant="outline" className="text-xs">
              FROM: {actualFromColumns.length}
            </Badge>
            <Badge variant="outline" className="text-xs">
              TO: {actualToColumns.length}
            </Badge>
          </div>
        </CardContent>
      </Card>

      {/* 매핑 통계 */}
      <Card className="mt-4 bg-muted/50 py-2">
        <CardContent className="p-4">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-3">
              <div>
                <div className="font-semibold text-foreground">매핑 진행 상황</div>
                <div className="text-sm text-muted-foreground">
                  총 {toTableColumns.length}개 컬럼 중{" "}
                  <span className="font-bold text-primary">
                    {columnMappings.filter((m) => m.fromColumnName || (m.defaultValue && m.defaultValue.trim())).length}
                    개
                  </span>{" "}
                  완료
                </div>
              </div>
            </div>
            <div className="text-right">
              <div className="text-2xl font-bold text-foreground">
                {Math.round(
                  (columnMappings.filter((m) => m.fromColumnName || (m.defaultValue && m.defaultValue.trim())).length /
                    actualToColumns.length) *
                    100,
                )}
                %
              </div>
              <div className="text-xs text-muted-foreground">완료율</div>
            </div>
          </div>
          <div className="mt-3">
            <Progress
              value={
                (columnMappings.filter((m) => m.fromColumnName || (m.defaultValue && m.defaultValue.trim())).length /
                  actualToColumns.length) *
                100
              }
              className="h-2"
            />
          </div>
        </CardContent>
      </Card>
    </div>
  );
};
