"use client";

import React, { useState, useEffect, useCallback, useMemo } from "react";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Checkbox } from "@/components/ui/checkbox";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Label } from "@/components/ui/label";
import { Calendar } from "@/components/ui/calendar";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Button } from "@/components/ui/button";
import { CalendarIcon, Upload, Loader2 } from "lucide-react";
import { format } from "date-fns";
import { ko } from "date-fns/locale";
import { ColumnInfo } from "@/lib/api/dataflow";
import { EntityReferenceAPI, EntityReferenceOption } from "@/lib/api/entityReference";

interface WebTypeInputProps {
  column: ColumnInfo;
  value: string | undefined;
  onChange: (value: string) => void;
  className?: string;
  placeholder?: string;
  tableName?: string; // 테이블명을 별도로 전달받음
}

export const WebTypeInput: React.FC<WebTypeInputProps> = ({
  column,
  value,
  onChange,
  className = "",
  placeholder,
  tableName,
}) => {
  // tableName은 props 또는 column.tableName에서 가져옴
  const effectiveTableName = tableName || (column as ColumnInfo & { tableName?: string }).tableName;
  const webType = column.webType || "text";
  const [entityOptions, setEntityOptions] = useState<EntityReferenceOption[]>([]);
  const [codeOptions, setCodeOptions] = useState<EntityReferenceOption[]>([]);
  const [loading, setLoading] = useState(false);

  // detailSettings 안전하게 파싱 (메모이제이션)
  const { detailSettings, fallbackCodeCategory } = useMemo(() => {
    let parsedSettings: Record<string, unknown> = {};
    let fallbackCategory = "";

    if (column.detailSettings && typeof column.detailSettings === "string") {
      // JSON 형태인지 확인 ('{' 또는 '[' 로 시작하는지)
      const trimmed = column.detailSettings.trim();
      if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
        try {
          parsedSettings = JSON.parse(column.detailSettings);
        } catch {
          parsedSettings = {};
        }
      } else {
        // JSON이 아닌 일반 문자열인 경우, code 타입이면 codeCategory로 사용
        if (webType === "code") {
          // "공통코드: 상태" 형태에서 실제 코드 추출 시도
          if (column.detailSettings.includes(":")) {
            const parts = column.detailSettings.split(":");
            if (parts.length >= 2) {
              fallbackCategory = parts[1].trim();
            } else {
              fallbackCategory = column.detailSettings;
            }
          } else {
            fallbackCategory = column.detailSettings;
          }
        }
        parsedSettings = {};
      }
    } else if (column.detailSettings && typeof column.detailSettings === "object") {
      parsedSettings = column.detailSettings;
    }

    return { detailSettings: parsedSettings, fallbackCodeCategory: fallbackCategory };
  }, [column.detailSettings, webType]);

  const loadEntityData = useCallback(async () => {
    try {
      setLoading(true);

      // entity 타입은 반드시 effectiveTableName과 columnName이 있어야 함
      if (!effectiveTableName || !column.columnName) {
        throw new Error("Entity 타입에는 tableName과 columnName이 필요합니다.");
      }

      const data = await EntityReferenceAPI.getEntityReferenceData(effectiveTableName, column.columnName, {
        limit: 100,
      });
      setEntityOptions(data.options);
    } catch {
      setEntityOptions([]);
    } finally {
      setLoading(false);
    }
  }, [effectiveTableName, column.columnName]);

  const loadCodeData = useCallback(async () => {
    try {
      setLoading(true);
      const codeCategory = column.codeCategory || (detailSettings.codeCategory as string) || fallbackCodeCategory;
      if (codeCategory) {
        const data = await EntityReferenceAPI.getCodeReferenceData(codeCategory, { limit: 100 });
        setCodeOptions(data.options);
      }
    } catch {
      setCodeOptions([]);
    } finally {
      setLoading(false);
    }
  }, [column.codeCategory, detailSettings.codeCategory, fallbackCodeCategory]);

  // webType에 따른 데이터 로드
  useEffect(() => {
    // 디버깅: entity 타입 필드 정보 확인
    if (column.columnName === "manager_name" || webType === "entity") {
      console.log("🔍 Entity 필드 디버깅:", {
        columnName: column.columnName,
        webType: webType,
        tableName: tableName,
        effectiveTableName: effectiveTableName,
        referenceTable: column.referenceTable,
        referenceColumn: column.referenceColumn,
        displayColumn: (column as any).displayColumn,
        shouldLoadEntity: webType === "entity" && effectiveTableName && column.columnName,
      });
    }

    if (webType === "entity" && effectiveTableName && column.columnName) {
      // entity 타입: 다른 테이블 참조
      console.log("🚀 Entity 데이터 로드 시작:", effectiveTableName, column.columnName);
      loadEntityData();
    } else if (webType === "code" && (column.codeCategory || detailSettings.codeCategory || fallbackCodeCategory)) {
      // code 타입: code_info 테이블에서 공통 코드 조회
      loadCodeData();
    }
    // text 타입: 일반 텍스트 입력
    // file 타입: 파일 업로드
  }, [
    webType,
    effectiveTableName,
    column.columnName,
    column.codeCategory,
    column.referenceTable,
    column.referenceColumn,
    (column as any).displayColumn,
    tableName,
    fallbackCodeCategory,
    detailSettings.codeCategory,
    loadEntityData,
    loadCodeData,
  ]);

  // 날짜/시간 타입일 때 기본값으로 현재 날짜/시간 설정
  useEffect(() => {
    const dateTimeTypes = ["date", "datetime", "timestamp"];

    // 컬럼명이나 데이터 타입으로 날짜 필드 판단
    const isDateColumn =
      dateTimeTypes.includes(webType) ||
      column.columnName?.toLowerCase().includes("date") ||
      column.columnName?.toLowerCase().includes("time") ||
      column.columnName === "regdate" ||
      column.columnName === "created_at" ||
      column.columnName === "updated_at";

    if (isDateColumn && (!value || value === "")) {
      const now = new Date();
      let formattedValue = "";

      if (webType === "date") {
        // 데이터베이스 타입이나 컬럼명으로 시간 포함 여부 판단
        const isTimestampType =
          column.dataType?.toLowerCase().includes("timestamp") ||
          column.columnName?.toLowerCase().includes("time") ||
          column.columnName === "regdate" ||
          column.columnName === "created_at" ||
          column.columnName === "updated_at";

        if (isTimestampType) {
          formattedValue = format(now, "yyyy-MM-dd HH:mm:ss");
        } else {
          formattedValue = format(now, "yyyy-MM-dd");
        }
      } else {
        // 컬럼명 기반 판단 시에도 시간 포함
        formattedValue = format(now, "yyyy-MM-dd HH:mm:ss");
      }

      onChange(formattedValue);
    }
  }, [webType, value, onChange, column.columnName, column.dataType]);

  // 공통 props
  const commonProps = {
    value: value || "",
    className,
  };

  // WebType별 렌더링 (column_labels의 webType을 정확히 따름)
  const actualWebType = webType;

  switch (actualWebType) {
    case "text":
      return (
        <Input
          {...commonProps}
          type="text"
          placeholder={placeholder || "텍스트 입력"}
          onChange={(e) => onChange(e.target.value)}
        />
      );

    case "number":
      return (
        <Input
          {...commonProps}
          type="number"
          placeholder={placeholder || "숫자 입력"}
          onChange={(e) => onChange(e.target.value)}
          min={detailSettings.min as number}
          max={detailSettings.max as number}
          step={(detailSettings.step as string) || "any"}
        />
      );

    case "date":
      // 데이터베이스 타입이나 컬럼명으로 시간 포함 여부 판단
      const isTimestampType =
        column.dataType?.toLowerCase().includes("timestamp") ||
        column.columnName?.toLowerCase().includes("time") ||
        column.columnName === "regdate" ||
        column.columnName === "created_at" ||
        column.columnName === "updated_at";

      if (isTimestampType) {
        // timestamp 타입이면 datetime-local input 사용 (시간까지 입력 가능)
        const datetimeValue = value ? value.replace(" ", "T").substring(0, 16) : "";
        return (
          <Input
            {...commonProps}
            type="datetime-local"
            value={datetimeValue}
            onChange={(e) => {
              const inputValue = e.target.value;
              // datetime-local 형식 (YYYY-MM-DDTHH:mm)을 DB 형식 (YYYY-MM-DD HH:mm:ss)으로 변환
              const formattedValue = inputValue ? `${inputValue.replace("T", " ")}:00` : "";
              onChange(formattedValue);
            }}
            placeholder={placeholder || "날짜와 시간 선택"}
          />
        );
      } else {
        // 순수 date 타입이면 달력 팝업 사용
        const dateValue = value ? new Date(value) : undefined;
        return (
          <Popover>
            <PopoverTrigger asChild>
              <Button
                variant="outline"
                className={`justify-start text-left font-normal ${className} ${!value && "text-muted-foreground"}`}
              >
                <CalendarIcon className="mr-2 h-4 w-4" />
                {dateValue ? format(dateValue, "PPP", { locale: ko }) : placeholder || "날짜 선택"}
              </Button>
            </PopoverTrigger>
            <PopoverContent className="w-auto p-0" align="start">
              <Calendar
                mode="single"
                selected={dateValue}
                onSelect={(date) => onChange(date ? format(date, "yyyy-MM-dd") : "")}
                initialFocus
              />
            </PopoverContent>
          </Popover>
        );
      }

    case "textarea":
      return (
        <Textarea
          {...commonProps}
          placeholder={placeholder || "여러 줄 텍스트 입력"}
          onChange={(e) => onChange(e.target.value)}
          rows={(detailSettings.rows as number) || 3}
        />
      );

    case "select":
      const selectOptions = (detailSettings.options as { value: string; label?: string }[]) || [];
      return (
        <Select value={value || ""} onValueChange={onChange}>
          <SelectTrigger className={className}>
            <SelectValue placeholder={placeholder || "선택하세요"} />
          </SelectTrigger>
          <SelectContent>
            {selectOptions.map((option: { value: string; label?: string }) => (
              <SelectItem key={option.value} value={option.value}>
                {option.label || option.value}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      );

    case "checkbox":
      return (
        <div className={`flex items-center space-x-2 ${className}`}>
          <Checkbox
            id={`checkbox-${column.columnName}`}
            checked={value === "true" || value === "1"}
            onCheckedChange={(checked) => onChange(checked ? "true" : "false")}
          />
          <Label htmlFor={`checkbox-${column.columnName}`} className="text-sm">
            {(detailSettings.label as string) || column.columnLabel || column.columnName}
          </Label>
        </div>
      );

    case "radio":
      const radioOptions = (detailSettings.options as { value: string; label?: string }[]) || [];
      return (
        <RadioGroup value={value || ""} onValueChange={onChange} className={className}>
          {radioOptions.map((option: { value: string; label?: string }) => (
            <div key={option.value} className="flex items-center space-x-2">
              <RadioGroupItem value={option.value} id={`radio-${column.columnName}-${option.value}`} />
              <Label htmlFor={`radio-${column.columnName}-${option.value}`} className="text-sm">
                {option.label || option.value}
              </Label>
            </div>
          ))}
        </RadioGroup>
      );

    case "code":
      // 공통코드 선택 - 실제 API에서 코드 목록 가져옴
      const codeCategory = column.codeCategory || (detailSettings.codeCategory as string) || fallbackCodeCategory;
      return (
        <Select value={value || ""} onValueChange={onChange} disabled={loading}>
          <SelectTrigger className={className}>
            <SelectValue placeholder={loading ? "코드 로딩 중..." : placeholder || `${codeCategory || "코드"} 선택`} />
            {loading && <Loader2 className="h-4 w-4 animate-spin" />}
          </SelectTrigger>
          <SelectContent>
            {codeOptions.length === 0 && !loading ? (
              <SelectItem value="__no_data__" disabled>
                사용 가능한 코드가 없습니다
              </SelectItem>
            ) : (
              codeOptions.map((option) => (
                <SelectItem key={option.value} value={option.value}>
                  {option.label}
                </SelectItem>
              ))
            )}
          </SelectContent>
        </Select>
      );

    case "entity":
      // 엔티티 참조 - 실제 참조 테이블에서 데이터 가져옴
      const referenceTable = column.referenceTable || (detailSettings.referenceTable as string);
      return (
        <Select value={value || ""} onValueChange={onChange} disabled={loading}>
          <SelectTrigger className={className}>
            <SelectValue placeholder={loading ? "데이터 로딩 중..." : placeholder || `${referenceTable} 선택`} />
            {loading && <Loader2 className="h-4 w-4 animate-spin" />}
          </SelectTrigger>
          <SelectContent>
            {entityOptions.length === 0 && !loading ? (
              <SelectItem value="__no_data__" disabled>
                사용 가능한 데이터가 없습니다
              </SelectItem>
            ) : (
              entityOptions.map((option) => (
                <SelectItem key={option.value} value={option.value}>
                  {option.label}
                </SelectItem>
              ))
            )}
          </SelectContent>
        </Select>
      );

    case "file":
      return (
        <div className={`space-y-2 ${className}`}>
          <Input
            type="file"
            onChange={(e) => {
              const file = e.target.files?.[0];
              if (file) {
                onChange(file.name); // 실제로는 파일 업로드 처리 필요
              }
            }}
            accept={detailSettings.accept as string}
            multiple={detailSettings.multiple as boolean}
          />
          {value && (
            <div className="flex items-center gap-2 text-sm text-muted-foreground">
              <Upload className="h-4 w-4" />
              <span>선택된 파일: {value}</span>
            </div>
          )}
        </div>
      );

    default:
      // 기본적으로 text input 사용
      return (
        <Input
          {...commonProps}
          type="text"
          placeholder={placeholder || "값 입력"}
          onChange={(e) => onChange(e.target.value)}
        />
      );
  }
};
