/**
 * 컬럼 추가 모달 컴포넌트
 * 기존 테이블에 새로운 컬럼을 추가하기 위한 모달
 */

"use client";

import { useState, useEffect } from "react";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Checkbox } from "@/components/ui/checkbox";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Loader2, Plus, AlertCircle } from "lucide-react";
import { toast } from "sonner";
import { ddlApi } from "../../lib/api/ddl";
import {
  AddColumnModalProps,
  CreateColumnDefinition,
  VALIDATION_RULES,
  RESERVED_WORDS,
  RESERVED_COLUMNS,
} from "../../types/ddl";
import { INPUT_TYPE_OPTIONS } from "../../types/input-types";

export function AddColumnModal({ isOpen, onClose, tableName, onSuccess }: AddColumnModalProps) {
  const [column, setColumn] = useState<CreateColumnDefinition>({
    name: "",
    label: "",
    inputType: "text",
    nullable: true,
    order: 0,
  });
  const [loading, setLoading] = useState(false);
  const [validationErrors, setValidationErrors] = useState<string[]>([]);

  /**
   * 모달 리셋
   */
  const resetModal = () => {
    setColumn({
      name: "",
      label: "",
      inputType: "text",
      nullable: true,
      order: 0,
    });
    setValidationErrors([]);
  };

  /**
   * 모달 열림/닫힘 시 리셋
   */
  useEffect(() => {
    if (isOpen) {
      resetModal();
    }
  }, [isOpen]);

  /**
   * 컬럼 정보 업데이트
   */
  const updateColumn = (updates: Partial<CreateColumnDefinition>) => {
    const newColumn = { ...column, ...updates };
    setColumn(newColumn);

    // 업데이트 후 검증
    validateColumn(newColumn);
  };

  /**
   * 컬럼 검증
   */
  const validateColumn = (columnData: CreateColumnDefinition) => {
    const errors: string[] = [];

    // 컬럼명 검증
    if (!columnData.name) {
      errors.push("컬럼명은 필수입니다.");
    } else {
      if (!VALIDATION_RULES.columnName.pattern.test(columnData.name)) {
        errors.push(VALIDATION_RULES.columnName.errorMessage);
      }

      if (
        columnData.name.length < VALIDATION_RULES.columnName.minLength ||
        columnData.name.length > VALIDATION_RULES.columnName.maxLength
      ) {
        errors.push(
          `컬럼명은 ${VALIDATION_RULES.columnName.minLength}-${VALIDATION_RULES.columnName.maxLength}자여야 합니다.`,
        );
      }

      // 예약어 검증
      if (RESERVED_WORDS.includes(columnData.name.toLowerCase() as any)) {
        errors.push("SQL 예약어는 컬럼명으로 사용할 수 없습니다.");
      }

      // 예약된 컬럼명 검증
      if (RESERVED_COLUMNS.includes(columnData.name.toLowerCase() as any)) {
        errors.push("이미 자동 추가되는 기본 컬럼명입니다.");
      }

      // 네이밍 컨벤션 검증
      if (columnData.name.startsWith("_") || columnData.name.endsWith("_")) {
        errors.push("컬럼명은 언더스코어로 시작하거나 끝날 수 없습니다.");
      }

      if (columnData.name.includes("__")) {
        errors.push("컬럼명에 연속된 언더스코어는 사용할 수 없습니다.");
      }
    }

    // 입력타입 검증
    if (!columnData.inputType) {
      errors.push("입력타입을 선택해주세요.");
    }

    // 길이 검증 (길이를 지원하는 타입인 경우)
    const inputTypeOption = INPUT_TYPE_OPTIONS.find((opt) => opt.value === columnData.inputType);
    if (inputTypeOption?.supportsLength && columnData.length !== undefined) {
      if (
        columnData.length < VALIDATION_RULES.columnLength.min ||
        columnData.length > VALIDATION_RULES.columnLength.max
      ) {
        errors.push(VALIDATION_RULES.columnLength.errorMessage);
      }
    }

    setValidationErrors(errors);
    return errors.length === 0;
  };

  /**
   * 입력타입 변경 처리
   */
  const handleInputTypeChange = (inputType: string) => {
    const inputTypeOption = INPUT_TYPE_OPTIONS.find((opt) => opt.value === inputType);
    const updates: Partial<CreateColumnDefinition> = { inputType: inputType as any };

    // 길이를 지원하는 타입이고 현재 길이가 없으면 기본값 설정
    if (inputTypeOption?.supportsLength && !column.length && inputTypeOption.defaultLength) {
      updates.length = inputTypeOption.defaultLength;
    }

    // 길이를 지원하지 않는 타입이면 길이 제거
    if (!inputTypeOption?.supportsLength) {
      updates.length = undefined;
    }

    updateColumn(updates);
  };

  /**
   * 컬럼 추가 실행
   */
  const handleAddColumn = async () => {
    if (!validateColumn(column)) {
      toast.error("입력값을 확인해주세요.");
      return;
    }

    setLoading(true);
    try {
      const result = await ddlApi.addColumn(tableName, { column });

      if (result.success) {
        toast.success(result.message);
        onSuccess(result);
        onClose();
      } else {
        toast.error(result.error?.details || result.message);
      }
    } catch (error: any) {
      // console.error("컬럼 추가 실패:", error);
      toast.error(error.response?.data?.error?.details || "컬럼 추가에 실패했습니다.");
    } finally {
      setLoading(false);
    }
  };

  /**
   * 폼 유효성 확인
   */
  const isFormValid = validationErrors.length === 0 && column.name && column.inputType;

  const inputTypeOption = INPUT_TYPE_OPTIONS.find((opt) => opt.value === column.inputType);

  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent className="max-w-2xl">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Plus className="h-5 w-5" />
            컬럼 추가 - {tableName}
          </DialogTitle>
        </DialogHeader>

        <div className="space-y-6">
          {/* 검증 오류 표시 */}
          {validationErrors.length > 0 && (
            <Alert variant="destructive">
              <AlertCircle className="h-4 w-4" />
              <AlertDescription>
                <div className="space-y-1">
                  {validationErrors.map((error, index) => (
                    <div key={index}>• {error}</div>
                  ))}
                </div>
              </AlertDescription>
            </Alert>
          )}

          {/* 기본 정보 */}
          <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
            <div className="space-y-2">
              <Label htmlFor="columnName">
                컬럼명 <span className="text-destructive">*</span>
              </Label>
              <Input
                id="columnName"
                value={column.name}
                onChange={(e) => updateColumn({ name: e.target.value })}
                placeholder="column_name"
                disabled={loading}
                className={validationErrors.some((e) => e.includes("컬럼명")) ? "border-destructive/30" : ""}
              />
              <p className="text-muted-foreground text-xs">영문자로 시작, 영문자/숫자/언더스코어만 사용 가능</p>
            </div>

            <div className="space-y-2">
              <Label htmlFor="columnLabel">라벨</Label>
              <Input
                id="columnLabel"
                value={column.label || ""}
                onChange={(e) => updateColumn({ label: e.target.value })}
                placeholder="컬럼 라벨"
                disabled={loading}
              />
              <p className="text-muted-foreground text-xs">화면에 표시될 라벨 (선택사항)</p>
            </div>
          </div>

          {/* 타입 및 속성 */}
          <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
            <div className="space-y-2">
              <Label>
                입력타입 <span className="text-destructive">*</span>
              </Label>
              <Select value={column.inputType} onValueChange={handleInputTypeChange} disabled={loading}>
                <SelectTrigger>
                  <SelectValue placeholder="입력타입 선택" />
                </SelectTrigger>
                <SelectContent>
                  {INPUT_TYPE_OPTIONS.map((option) => (
                    <SelectItem key={option.value} value={option.value}>
                      <div>
                        <div className="font-medium">{option.label}</div>
                        {option.description && (
                          <div className="text-muted-foreground text-xs">{option.description}</div>
                        )}
                      </div>
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <div className="space-y-2">
              <Label htmlFor="columnLength">길이</Label>
              <Input
                id="columnLength"
                type="number"
                value={column.length || ""}
                onChange={(e) =>
                  updateColumn({
                    length: e.target.value ? parseInt(e.target.value) : undefined,
                  })
                }
                placeholder={inputTypeOption?.defaultLength?.toString() || ""}
                disabled={loading || !inputTypeOption?.supportsLength}
                min={1}
                max={65535}
              />
              <p className="text-muted-foreground text-xs">
                {inputTypeOption?.supportsLength ? "1-65535 범위에서 설정 가능" : "이 타입은 길이 설정이 불가능합니다"}
              </p>
            </div>
          </div>

          {/* 기본값 및 NULL 허용 */}
          <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
            <div className="space-y-2">
              <Label htmlFor="defaultValue">기본값</Label>
              <Input
                id="defaultValue"
                value={column.defaultValue || ""}
                onChange={(e) => updateColumn({ defaultValue: e.target.value })}
                placeholder="기본값 (선택사항)"
                disabled={loading}
              />
            </div>

            <div className="flex items-center space-x-2 pt-6">
              <Checkbox
                id="required"
                checked={!column.nullable}
                onCheckedChange={(checked) => updateColumn({ nullable: !checked })}
                disabled={loading}
              />
              <Label htmlFor="required" className="text-sm font-medium">
                필수 입력 (NOT NULL)
              </Label>
            </div>
          </div>

          {/* 설명 */}
          <div className="space-y-2">
            <Label htmlFor="description">설명</Label>
            <Textarea
              id="description"
              value={column.description || ""}
              onChange={(e) => updateColumn({ description: e.target.value })}
              placeholder="컬럼에 대한 설명 (선택사항)"
              disabled={loading}
              rows={3}
            />
          </div>

          {/* 안내 사항 */}
          <Alert>
            <AlertCircle className="h-4 w-4" />
            <AlertDescription>
              컬럼 추가 후에는 해당 컬럼을 삭제하거나 타입을 변경할 수 없습니다. 신중하게 검토 후 추가해주세요.
            </AlertDescription>
          </Alert>
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={onClose} disabled={loading}>
            취소
          </Button>

          <Button
            onClick={handleAddColumn}
            disabled={!isFormValid || loading}
            className="bg-primary hover:bg-primary/90"
          >
            {loading ? (
              <>
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                추가 중...
              </>
            ) : (
              "컬럼 추가"
            )}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
