"use client";

import React, { useState, useCallback, useEffect } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";
import { Badge } from "@/components/ui/badge";
import { Plus, Trash2, Database, ArrowRight, Settings } from "lucide-react";

import {
  DataMappingConfig,
  DataDirection,
  TableInfo,
  FieldMapping,
  InboundMapping,
  OutboundMapping,
  DATA_DIRECTION_OPTIONS,
  INSERT_MODE_OPTIONS,
} from "@/types/external-call/DataMappingTypes";

import { FieldMappingEditor } from "./FieldMappingEditor";

interface DataMappingSettingsProps {
  config: DataMappingConfig;
  onConfigChange: (config: DataMappingConfig) => void;
  httpMethod: string;
  availableTables?: TableInfo[];
  readonly?: boolean;
  tablesLoading?: boolean;
}

export const DataMappingSettings: React.FC<DataMappingSettingsProps> = ({
  config,
  onConfigChange,
  httpMethod,
  availableTables = [],
  readonly = false,
  tablesLoading = false,
}) => {
  const [localConfig, setLocalConfig] = useState<DataMappingConfig>(config);

  // 컴포넌트 변경 시 로컬 상태 동기화
  useEffect(() => {
    setLocalConfig(config);
  }, [config]);

  // HTTP 메서드에 따른 권장 방향 결정
  const getRecommendedDirection = useCallback((method: string): DataDirection => {
    const upperMethod = method.toUpperCase();
    if (upperMethod === "GET") return "inbound";
    if (["POST", "PUT", "PATCH"].includes(upperMethod)) return "outbound";
    return "none";
  }, []);

  // 방향 변경 핸들러
  const handleDirectionChange = useCallback(
    (direction: DataDirection) => {
      const newConfig = {
        ...localConfig,
        direction,
        // 방향에 따라 불필요한 매핑 제거
        inboundMapping:
          direction === "inbound" || direction === "bidirectional"
            ? localConfig.inboundMapping || {
                targetTable: "",
                fieldMappings: [],
                insertMode: "insert" as const,
              }
            : undefined,
        outboundMapping:
          direction === "outbound" || direction === "bidirectional"
            ? localConfig.outboundMapping || {
                sourceTable: "",
                fieldMappings: [],
              }
            : undefined,
      };
      setLocalConfig(newConfig);
      onConfigChange(newConfig);
    },
    [localConfig, onConfigChange],
  );

  // Inbound 매핑 업데이트
  const handleInboundMappingChange = useCallback(
    (mapping: Partial<InboundMapping>) => {
      const newConfig = {
        ...localConfig,
        inboundMapping: {
          ...localConfig.inboundMapping!,
          ...mapping,
        },
      };
      setLocalConfig(newConfig);
      onConfigChange(newConfig);
    },
    [localConfig, onConfigChange],
  );

  // Outbound 매핑 업데이트
  const handleOutboundMappingChange = useCallback(
    (mapping: Partial<OutboundMapping>) => {
      const newConfig = {
        ...localConfig,
        outboundMapping: {
          ...localConfig.outboundMapping!,
          ...mapping,
        },
      };
      setLocalConfig(newConfig);
      onConfigChange(newConfig);
    },
    [localConfig, onConfigChange],
  );

  // 필드 매핑 업데이트 (Inbound)
  const handleInboundFieldMappingsChange = useCallback(
    (fieldMappings: FieldMapping[]) => {
      handleInboundMappingChange({ fieldMappings });
    },
    [handleInboundMappingChange],
  );

  // 필드 매핑 업데이트 (Outbound)
  const handleOutboundFieldMappingsChange = useCallback(
    (fieldMappings: FieldMapping[]) => {
      handleOutboundMappingChange({ fieldMappings });
    },
    [handleOutboundMappingChange],
  );

  // 검증 함수
  const isConfigValid = useCallback(() => {
    if (localConfig.direction === "none") return true;

    if (
      (localConfig.direction === "inbound" || localConfig.direction === "bidirectional") &&
      localConfig.inboundMapping
    ) {
      if (!localConfig.inboundMapping.targetTable) return false;
      if (localConfig.inboundMapping.fieldMappings.length === 0) return false;
    }

    if (
      (localConfig.direction === "outbound" || localConfig.direction === "bidirectional") &&
      localConfig.outboundMapping
    ) {
      if (!localConfig.outboundMapping.sourceTable) return false;
      if (localConfig.outboundMapping.fieldMappings.length === 0) return false;
    }

    return true;
  }, [localConfig]);

  const recommendedDirection = getRecommendedDirection(httpMethod);

  return (
    <Card className="w-full">
      <CardHeader className="pb-3">
        <CardTitle className="flex items-center gap-2">
          <Database className="h-5 w-5" />
          데이터 매핑 설정
          {!isConfigValid() && <Badge variant="destructive">설정 필요</Badge>}
          {isConfigValid() && localConfig.direction !== "none" && <Badge variant="default">설정 완료</Badge>}
        </CardTitle>
        <p className="text-muted-foreground text-sm">외부 API와 내부 테이블 간의 데이터 매핑을 설정합니다.</p>
      </CardHeader>
      <CardContent className="space-y-4">
        {/* 매핑 방향 선택 */}
        <div className="space-y-2">
          <Label>매핑 방향</Label>
          <Select value={localConfig.direction} onValueChange={handleDirectionChange} disabled={readonly}>
            <SelectTrigger>
              <SelectValue placeholder="매핑 방향을 선택하세요" />
            </SelectTrigger>
            <SelectContent>
              {DATA_DIRECTION_OPTIONS.map((option) => (
                <SelectItem key={option.value} value={option.value}>
                  <div className="flex items-center gap-2">
                    {option.label}
                    {option.value === recommendedDirection && (
                      <Badge variant="secondary" className="text-xs">
                        권장
                      </Badge>
                    )}
                  </div>
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          {localConfig.direction !== recommendedDirection && recommendedDirection !== "none" && (
            <p className="text-xs text-amber-600">
              💡 {httpMethod} 요청에는 "{DATA_DIRECTION_OPTIONS.find((o) => o.value === recommendedDirection)?.label}"
              방향이 권장됩니다.
            </p>
          )}
        </div>

        {/* 매핑 설정 탭 */}
        {localConfig.direction !== "none" && (
          <Tabs
            defaultValue={localConfig.direction === "bidirectional" ? "inbound" : localConfig.direction}
            className="w-full"
          >
            <TabsList className="grid w-full grid-cols-2">
              {(localConfig.direction === "inbound" || localConfig.direction === "bidirectional") && (
                <TabsTrigger value="inbound">
                  <ArrowRight className="mr-1 h-4 w-4" />
                  외부 → 내부
                </TabsTrigger>
              )}
              {(localConfig.direction === "outbound" || localConfig.direction === "bidirectional") && (
                <TabsTrigger value="outbound">
                  <ArrowRight className="mr-1 h-4 w-4 rotate-180" />
                  내부 → 외부
                </TabsTrigger>
              )}
            </TabsList>

            {/* Inbound 매핑 설정 */}
            {(localConfig.direction === "inbound" || localConfig.direction === "bidirectional") && (
              <TabsContent value="inbound" className="space-y-4">
                <div className="grid grid-cols-2 gap-4">
                  <div className="space-y-2">
                    <Label>대상 테이블</Label>
                    <Select
                      value={localConfig.inboundMapping?.targetTable || ""}
                      onValueChange={(value) => handleInboundMappingChange({ targetTable: value })}
                      disabled={readonly || tablesLoading}
                    >
                      <SelectTrigger>
                        <SelectValue placeholder={tablesLoading ? "테이블 목록 로딩 중..." : "저장할 테이블을 선택하세요"} />
                      </SelectTrigger>
                      <SelectContent>
                        {/* Radix UI Select v2.x: 빈 문자열 value="" 금지 → "__placeholder__" 사용 */}
                        {tablesLoading ? (
                          <SelectItem value="__placeholder__" disabled>
                            테이블 목록 로딩 중...
                          </SelectItem>
                        ) : availableTables.length === 0 ? (
                          <SelectItem value="__placeholder__" disabled>
                            사용 가능한 테이블이 없습니다
                          </SelectItem>
                        ) : (
                          availableTables.map((table) => (
                            <SelectItem key={table.name} value={table.name}>
                              {table.displayName || table.name}
                            </SelectItem>
                          ))
                        )}
                      </SelectContent>
                    </Select>
                  </div>

                  <div className="space-y-2">
                    <Label>저장 모드</Label>
                    <Select
                      value={localConfig.inboundMapping?.insertMode || "insert"}
                      onValueChange={(value) => handleInboundMappingChange({ insertMode: value as any })}
                      disabled={readonly}
                    >
                      <SelectTrigger>
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        {INSERT_MODE_OPTIONS.map((option) => (
                          <SelectItem key={option.value} value={option.value}>
                            {option.label}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                </div>

                {/* 키 필드 설정 (upsert/update 모드일 때) */}
                {localConfig.inboundMapping?.insertMode !== "insert" && (
                  <div className="space-y-2">
                    <Label>키 필드</Label>
                    <Input
                      value={localConfig.inboundMapping?.keyFields?.join(", ") || ""}
                      onChange={(e) =>
                        handleInboundMappingChange({
                          keyFields: e.target.value
                            .split(",")
                            .map((s) => s.trim())
                            .filter(Boolean),
                        })
                      }
                      placeholder="id, code"
                      disabled={readonly}
                    />
                    <p className="text-muted-foreground text-xs">
                      업데이트/업서트 시 사용할 키 필드를 쉼표로 구분하여 입력하세요.
                    </p>
                  </div>
                )}

                {/* 필드 매핑 에디터 */}
                {localConfig.inboundMapping?.targetTable && (
                  <FieldMappingEditor
                    mappings={localConfig.inboundMapping.fieldMappings}
                    onMappingsChange={handleInboundFieldMappingsChange}
                    direction="inbound"
                    targetTable={availableTables.find((t) => t.name === localConfig.inboundMapping?.targetTable)}
                    readonly={readonly}
                  />
                )}
              </TabsContent>
            )}

            {/* Outbound 매핑 설정 */}
            {(localConfig.direction === "outbound" || localConfig.direction === "bidirectional") && (
              <TabsContent value="outbound" className="space-y-4">
                <div className="grid grid-cols-1 gap-4">
                  <div className="space-y-2">
                    <Label>소스 테이블</Label>
                    <Select
                      value={localConfig.outboundMapping?.sourceTable || ""}
                      onValueChange={(value) => handleOutboundMappingChange({ sourceTable: value })}
                      disabled={readonly}
                    >
                      <SelectTrigger>
                        <SelectValue placeholder="데이터를 가져올 테이블을 선택하세요" />
                      </SelectTrigger>
                      <SelectContent>
                        {availableTables.map((table) => (
                          <SelectItem key={table.name} value={table.name}>
                            {table.displayName || table.name}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                </div>

                {/* 소스 필터 조건 */}
                <div className="space-y-2">
                  <Label>필터 조건 (선택사항)</Label>
                  <Textarea
                    value={localConfig.outboundMapping?.sourceFilter || ""}
                    onChange={(e) => handleOutboundMappingChange({ sourceFilter: e.target.value })}
                    placeholder="status = 'active' AND created_at >= '2024-01-01'"
                    disabled={readonly}
                    rows={2}
                  />
                  <p className="text-muted-foreground text-xs">
                    WHERE 절에 사용할 조건을 입력하세요. 비어있으면 모든 데이터를 가져옵니다.
                  </p>
                </div>

                {/* 필드 매핑 에디터 */}
                {localConfig.outboundMapping?.sourceTable && (
                  <FieldMappingEditor
                    mappings={localConfig.outboundMapping.fieldMappings}
                    onMappingsChange={handleOutboundFieldMappingsChange}
                    direction="outbound"
                    sourceTable={availableTables.find((t) => t.name === localConfig.outboundMapping?.sourceTable)}
                    readonly={readonly}
                  />
                )}
              </TabsContent>
            )}
          </Tabs>
        )}

        {/* 설정 요약 */}
        {localConfig.direction !== "none" && (
          <div className="bg-muted mt-4 rounded-lg p-3">
            <h4 className="mb-2 text-sm font-medium">설정 요약</h4>
            <div className="text-muted-foreground space-y-1 text-xs">
              <div>방향: {DATA_DIRECTION_OPTIONS.find((o) => o.value === localConfig.direction)?.label}</div>
              {localConfig.inboundMapping && (
                <div>
                  외부 → {localConfig.inboundMapping.targetTable}({localConfig.inboundMapping.fieldMappings.length}개
                  필드)
                </div>
              )}
              {localConfig.outboundMapping && (
                <div>
                  {localConfig.outboundMapping.sourceTable} → 외부 ({localConfig.outboundMapping.fieldMappings.length}개
                  필드)
                </div>
              )}
            </div>
          </div>
        )}
      </CardContent>
    </Card>
  );
};
