/**
 * 컬럼 정의 테이블 컴포넌트
 * 테이블 생성 시 컬럼 정의를 위한 편집 가능한 테이블
 */

"use client";

import { useState } from "react";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";
import { X, AlertCircle } from "lucide-react";
import { Alert, AlertDescription } from "@/components/ui/alert";
import {
  CreateColumnDefinition,
  ColumnDefinitionTableProps,
  VALIDATION_RULES,
  RESERVED_WORDS,
  RESERVED_COLUMNS,
} from "../../types/ddl";
import { INPUT_TYPE_OPTIONS, USER_SELECTABLE_INPUT_TYPE_ORDER } from "../../types/input-types";

export function ColumnDefinitionTable({ columns, onChange, disabled = false }: ColumnDefinitionTableProps) {
  const [validationErrors, setValidationErrors] = useState<Record<number, string[]>>({});

  /**
   * 컬럼 정보 업데이트
   */
  const updateColumn = (index: number, updates: Partial<CreateColumnDefinition>) => {
    const newColumns = [...columns];
    newColumns[index] = { ...newColumns[index], ...updates };
    onChange(newColumns);

    // 업데이트 후 해당 컬럼 검증
    validateColumn(index, newColumns[index]);
  };

  /**
   * 컬럼 제거
   */
  const removeColumn = (index: number) => {
    if (columns.length <= 1) return; // 최소 1개 컬럼 유지

    const newColumns = columns.filter((_, i) => i !== index);
    onChange(newColumns);

    // 검증 오류도 함께 제거
    const newErrors = { ...validationErrors };
    delete newErrors[index];

    // 인덱스 재조정
    const adjustedErrors: Record<number, string[]> = {};
    Object.entries(newErrors).forEach(([key, value]) => {
      const idx = parseInt(key);
      if (idx > index) {
        adjustedErrors[idx - 1] = value;
      } else if (idx < index) {
        adjustedErrors[idx] = value;
      }
    });

    setValidationErrors(adjustedErrors);
  };

  /**
   * 개별 컬럼 검증
   */
  const validateColumn = (index: number, column: CreateColumnDefinition) => {
    const errors: string[] = [];

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

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

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

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

      // 중복 검증
      const duplicateCount = columns.filter((col) => col.name.toLowerCase() === column.name.toLowerCase()).length;
      if (duplicateCount > 1) {
        errors.push("중복된 컬럼명입니다");
      }
    }

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

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

    // 검증 오류 상태 업데이트
    setValidationErrors((prev) => ({
      ...prev,
      [index]: errors,
    }));

    return errors.length === 0;
  };

  /**
   * 입력타입 변경 시 길이 기본값 설정
   */
  const handleInputTypeChange = (index: number, inputType: string) => {
    const inputTypeOption = INPUT_TYPE_OPTIONS.find((opt) => opt.value === inputType) as any;
    const updates: Partial<CreateColumnDefinition> = { input_type: inputType as any };

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

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

    updateColumn(index, updates);
  };

  /**
   * 전체 검증 상태 확인
   */
  const hasValidationErrors = Object.values(validationErrors).some((errors) => errors.length > 0);

  return (
    <div className="space-y-4">
      {/* 검증 오류 요약 */}
      {hasValidationErrors && (
        <Alert variant="destructive">
          <AlertCircle className="h-4 w-4" />
          <AlertDescription>컬럼 정의에 오류가 있습니다. 각 컬럼의 오류를 확인해주세요.</AlertDescription>
        </Alert>
      )}

      {/* 컬럼 정의 테이블 */}
      <div className="overflow-hidden bg-card shadow-sm">
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead className="h-12 w-[150px] text-sm font-semibold">
                컬럼명 <span className="text-destructive">*</span>
              </TableHead>
              <TableHead className="h-12 w-[150px] text-sm font-semibold">라벨</TableHead>
              <TableHead className="h-12 w-[120px] text-sm font-semibold">
                입력타입 <span className="text-destructive">*</span>
              </TableHead>
              <TableHead className="h-12 w-[80px] text-sm font-semibold">필수</TableHead>
              <TableHead className="h-12 w-[100px] text-sm font-semibold">길이</TableHead>
              <TableHead className="h-12 w-[120px] text-sm font-semibold">기본값</TableHead>
              <TableHead className="h-12 text-sm font-semibold">설명</TableHead>
              <TableHead className="h-12 w-[50px] text-sm font-semibold"></TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {columns.map((column, index) => {
              const inputTypeOption = INPUT_TYPE_OPTIONS.find((opt) => opt.value === column.input_type) as any;
              const rowErrors = validationErrors[index] || [];
              const hasRowError = rowErrors.length > 0;

              return (
                <TableRow key={index} className={`transition-colors hover:bg-muted/50 ${hasRowError ? "bg-destructive/10" : ""}`}>
                  <TableCell className="h-16">
                    <div className="space-y-1">
                      <Input
                        value={column.name}
                        onChange={(e) => updateColumn(index, { name: e.target.value })}
                        placeholder="column_name"
                        disabled={disabled}
                        className={`text-sm ${hasRowError ? "border-destructive" : ""}`}
                      />
                      {rowErrors.length > 0 && (
                        <div className="space-y-1 text-xs text-destructive">
                          {rowErrors.map((error, i) => (
                            <div key={i}>{error}</div>
                          ))}
                        </div>
                      )}
                    </div>
                  </TableCell>

                  <TableCell className="h-16 text-sm">
                    <Input
                      value={column.label || ""}
                      onChange={(e) => updateColumn(index, { label: e.target.value })}
                      placeholder="컬럼 라벨"
                      disabled={disabled}
                      className="text-sm"
                    />
                  </TableCell>

                  <TableCell className="h-16 text-sm">
                    <Select
                      value={column.input_type}
                      onValueChange={(value) => handleInputTypeChange(index, value)}
                      disabled={disabled}
                    >
                      <SelectTrigger className="text-sm">
                        <SelectValue placeholder="입력 타입 선택" />
                      </SelectTrigger>
                      <SelectContent>
                        {INPUT_TYPE_OPTIONS
                          .filter((o) => USER_SELECTABLE_INPUT_TYPE_ORDER.includes(o.value as any))
                          .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>
                  </TableCell>

                  <TableCell className="h-16 text-sm">
                    <div className="flex items-center justify-center">
                      <Checkbox
                        checked={!column.nullable}
                        onCheckedChange={(checked) => updateColumn(index, { nullable: !checked })}
                        disabled={disabled}
                      />
                    </div>
                  </TableCell>

                  <TableCell className="h-16 text-sm">
                    <Input
                      type="number"
                      value={column.length || ""}
                      onChange={(e) =>
                        updateColumn(index, {
                          length: e.target.value ? parseInt(e.target.value) : undefined,
                        })
                      }
                      placeholder={inputTypeOption?.defaultLength?.toString() || ""}
                      disabled={disabled || !inputTypeOption?.supportsLength}
                      min={1}
                      max={65535}
                      className="text-sm"
                    />
                  </TableCell>

                  <TableCell className="h-16 text-sm">
                    <Input
                      value={column.default_value || ""}
                      onChange={(e) => updateColumn(index, { default_value: e.target.value })}
                      placeholder="기본값"
                      disabled={disabled}
                      className="text-sm"
                    />
                  </TableCell>

                  <TableCell className="h-16 text-sm">
                    <Textarea
                      value={column.description || ""}
                      onChange={(e) => updateColumn(index, { description: e.target.value })}
                      placeholder="컬럼 설명"
                      disabled={disabled}
                      rows={1}
                      className="min-h-[36px] resize-none text-sm"
                    />
                  </TableCell>

                  <TableCell className="h-16 text-sm">
                    <Button
                      type="button"
                      variant="ghost"
                      size="sm"
                      onClick={() => removeColumn(index)}
                      disabled={disabled || columns.length === 1}
                      className="h-8 w-8 p-0"
                    >
                      <X className="h-4 w-4" />
                    </Button>
                  </TableCell>
                </TableRow>
              );
            })}
          </TableBody>
        </Table>
      </div>

      {/* 도움말 */}
      <div className="text-muted-foreground space-y-1 text-sm">
        <div>• 컬럼명은 영문자로 시작하고 영문자, 숫자, 언더스코어만 사용 가능합니다.</div>
        <div>• 다음 컬럼들은 자동으로 추가됩니다: id (PK), created_date, updated_date, company_code</div>
        <div>• 필수 컬럼은 NOT NULL 제약조건이 추가됩니다.</div>
        <div>• 길이는 text, code, email, tel 등의 타입에서만 설정 가능합니다.</div>
      </div>
    </div>
  );
}
