"use client";

import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";

import { LoadingSpinner } from "@/components/common/LoadingSpinner";
import { ValidationMessage } from "@/components/common/ValidationMessage";
import { useCreateCode, useUpdateCode } from "@/hooks/queries/useCodes";
import { useCheckCodeDuplicate } from "@/hooks/queries/useValidation";
import { createCodeSchema, updateCodeSchema, type CreateCodeData, type UpdateCodeData } from "@/lib/schemas/commonCode";
import type { CodeInfo } from "@/types/commonCode";
import type { FieldError } from "react-hook-form";

interface CodeFormModalProps {
  isOpen: boolean;
  onClose: () => void;
  categoryCode: string;
  editingCode?: CodeInfo | null;
  codes: CodeInfo[];
}

// 에러 메시지를 안전하게 문자열로 변환하는 헬퍼 함수
const getErrorMessage = (error: FieldError | undefined): string => {
  if (!error) return "";
  if (typeof error === "string") return error;
  return error.message || "";
};

export function CodeFormModal({ isOpen, onClose, categoryCode, editingCode, codes }: CodeFormModalProps) {
  const createCodeMutation = useCreateCode();
  const updateCodeMutation = useUpdateCode();

  const isEditing = !!editingCode;

  // 검증 상태 관리
  const [validationStates, setValidationStates] = useState({
    codeValue: { enabled: false, value: "" },
    codeName: { enabled: false, value: "" },
    codeNameEng: { enabled: false, value: "" },
  });

  // 중복 검사 훅들
  const codeValueCheck = useCheckCodeDuplicate(
    categoryCode,
    "codeValue",
    validationStates.codeValue.value,
    isEditing ? editingCode?.codeValue || editingCode?.code_value : undefined,
    validationStates.codeValue.enabled,
  );

  const codeNameCheck = useCheckCodeDuplicate(
    categoryCode,
    "codeName",
    validationStates.codeName.value,
    isEditing ? editingCode?.codeValue || editingCode?.code_value : undefined,
    validationStates.codeName.enabled,
  );

  const codeNameEngCheck = useCheckCodeDuplicate(
    categoryCode,
    "codeNameEng",
    validationStates.codeNameEng.value,
    isEditing ? editingCode?.codeValue || editingCode?.code_value : undefined,
    validationStates.codeNameEng.enabled,
  );

  // 중복 검사 결과 확인
  const hasDuplicateErrors =
    (codeValueCheck.data?.isDuplicate && validationStates.codeValue.enabled) ||
    (codeNameCheck.data?.isDuplicate && validationStates.codeName.enabled) ||
    (codeNameEngCheck.data?.isDuplicate && validationStates.codeNameEng.enabled);

  // 중복 검사 로딩 중인지 확인
  const isDuplicateChecking = codeValueCheck.isLoading || codeNameCheck.isLoading || codeNameEngCheck.isLoading;

  // 폼 스키마 선택 (생성/수정에 따라)
  const schema = isEditing ? updateCodeSchema : createCodeSchema;

  const form = useForm({
    resolver: zodResolver(schema),
    mode: "onChange", // 실시간 검증 활성화
    defaultValues: {
      codeValue: "",
      codeName: "",
      codeNameEng: "",
      description: "",
      sortOrder: 1,
      ...(isEditing && { isActive: "Y" as const }),
    },
  });

  // 편집 모드일 때 기존 데이터 로드
  useEffect(() => {
    if (isOpen) {
      if (isEditing && editingCode) {
        // 수정 모드: 기존 데이터 로드 (codeValue는 표시용으로만 설정)
        form.reset({
          codeName: editingCode.codeName || editingCode.code_name,
          codeNameEng: editingCode.codeNameEng || editingCode.code_name_eng || "",
          description: editingCode.description || "",
          sortOrder: editingCode.sortOrder || editingCode.sort_order,
          isActive: (editingCode.isActive || editingCode.is_active) as "Y" | "N", // 타입 캐스팅
        });

        // codeValue는 별도로 설정 (표시용)
        form.setValue("codeValue" as any, editingCode.codeValue || editingCode.code_value);
      } else {
        // 새 코드 모드: 자동 순서 계산
        const maxSortOrder = codes.length > 0 ? Math.max(...codes.map((c) => c.sortOrder || c.sort_order)) : 0;

        form.reset({
          codeValue: "",
          codeName: "",
          codeNameEng: "",
          description: "",
          sortOrder: maxSortOrder + 1,
        });
      }
    }
  }, [isOpen, isEditing, editingCode, codes]);

  const handleSubmit = form.handleSubmit(async (data) => {
    try {
      if (isEditing && editingCode) {
        // 수정
        await updateCodeMutation.mutateAsync({
          categoryCode,
          codeValue: editingCode.codeValue || editingCode.code_value,
          data: data as UpdateCodeData,
        });
      } else {
        // 생성
        await createCodeMutation.mutateAsync({
          categoryCode,
          data: data as CreateCodeData,
        });
      }

      onClose();
      form.reset();
    } catch (error) {
      console.error("코드 저장 실패:", error);
    }
  });

  const isLoading = createCodeMutation.isPending || updateCodeMutation.isPending;

  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent className="max-w-[95vw] sm:max-w-[500px]">
        <DialogHeader>
          <DialogTitle className="text-base sm:text-lg">{isEditing ? "코드 수정" : "새 코드"}</DialogTitle>
        </DialogHeader>

        <form onSubmit={handleSubmit} className="space-y-3 sm:space-y-4">
          {/* 코드값 */}
          <div className="space-y-2">
            <Label htmlFor="codeValue" className="text-xs sm:text-sm">코드값 *</Label>
            <Input
              id="codeValue"
              {...form.register("codeValue")}
              disabled={isLoading || isEditing}
              placeholder="코드값을 입력하세요"
              className={(form.formState.errors as any)?.codeValue ? "h-8 text-xs sm:h-10 sm:text-sm border-destructive" : "h-8 text-xs sm:h-10 sm:text-sm"}
              onBlur={(e) => {
                const value = e.target.value.trim();
                if (value && !isEditing) {
                  setValidationStates((prev) => ({
                    ...prev,
                    codeValue: { enabled: true, value },
                  }));
                }
              }}
            />
            {(form.formState.errors as any)?.codeValue && (
              <p className="text-[10px] sm:text-xs text-destructive">{getErrorMessage((form.formState.errors as any)?.codeValue)}</p>
            )}
            {!isEditing && !(form.formState.errors as any)?.codeValue && (
              <ValidationMessage
                message={codeValueCheck.data?.message}
                isValid={!codeValueCheck.data?.isDuplicate}
                isLoading={codeValueCheck.isLoading}
              />
            )}
          </div>

          {/* 코드명 */}
          <div className="space-y-2">
            <Label htmlFor="codeName" className="text-xs sm:text-sm">코드명 *</Label>
            <Input
              id="codeName"
              {...form.register("codeName")}
              disabled={isLoading}
              placeholder="코드명을 입력하세요"
              className={form.formState.errors.codeName ? "h-8 text-xs sm:h-10 sm:text-sm border-destructive" : "h-8 text-xs sm:h-10 sm:text-sm"}
              onBlur={(e) => {
                const value = e.target.value.trim();
                if (value) {
                  setValidationStates((prev) => ({
                    ...prev,
                    codeName: { enabled: true, value },
                  }));
                }
              }}
            />
            {form.formState.errors.codeName && (
              <p className="text-[10px] sm:text-xs text-destructive">{getErrorMessage(form.formState.errors.codeName)}</p>
            )}
            {!form.formState.errors.codeName && (
              <ValidationMessage
                message={codeNameCheck.data?.message}
                isValid={!codeNameCheck.data?.isDuplicate}
                isLoading={codeNameCheck.isLoading}
              />
            )}
          </div>

          {/* 영문명 */}
          <div className="space-y-2">
            <Label htmlFor="codeNameEng" className="text-xs sm:text-sm">코드 영문명 *</Label>
            <Input
              id="codeNameEng"
              {...form.register("codeNameEng")}
              disabled={isLoading}
              placeholder="코드 영문명을 입력하세요"
              className={form.formState.errors.codeNameEng ? "h-8 text-xs sm:h-10 sm:text-sm border-destructive" : "h-8 text-xs sm:h-10 sm:text-sm"}
              onBlur={(e) => {
                const value = e.target.value.trim();
                if (value) {
                  setValidationStates((prev) => ({
                    ...prev,
                    codeNameEng: { enabled: true, value },
                  }));
                }
              }}
            />
            {form.formState.errors.codeNameEng && (
              <p className="text-[10px] sm:text-xs text-destructive">{getErrorMessage(form.formState.errors.codeNameEng)}</p>
            )}
            {!form.formState.errors.codeNameEng && (
              <ValidationMessage
                message={codeNameEngCheck.data?.message}
                isValid={!codeNameEngCheck.data?.isDuplicate}
                isLoading={codeNameEngCheck.isLoading}
              />
            )}
          </div>

          {/* 설명 */}
          <div className="space-y-2">
            <Label htmlFor="description" className="text-xs sm:text-sm">설명 *</Label>
            <Textarea
              id="description"
              {...form.register("description")}
              disabled={isLoading}
              placeholder="설명을 입력하세요"
              rows={3}
              className={form.formState.errors.description ? "text-xs sm:text-sm border-destructive" : "text-xs sm:text-sm"}
            />
            {form.formState.errors.description && (
              <p className="text-[10px] sm:text-xs text-destructive">{getErrorMessage(form.formState.errors.description)}</p>
            )}
          </div>

          {/* 정렬 순서 */}
          <div className="space-y-2">
            <Label htmlFor="sortOrder" className="text-xs sm:text-sm">정렬 순서</Label>
            <Input
              id="sortOrder"
              type="number"
              {...form.register("sortOrder", { valueAsNumber: true })}
              disabled={isLoading}
              min={1}
              className={form.formState.errors.sortOrder ? "h-8 text-xs sm:h-10 sm:text-sm border-destructive" : "h-8 text-xs sm:h-10 sm:text-sm"}
            />
            {form.formState.errors.sortOrder && (
              <p className="text-[10px] sm:text-xs text-destructive">{getErrorMessage(form.formState.errors.sortOrder)}</p>
            )}
          </div>

          {/* 활성 상태 (수정 시에만) */}
          {isEditing && (
            <div className="flex items-center gap-2">
              <Switch
                id="isActive"
                checked={form.watch("isActive") === "Y"}
                onCheckedChange={(checked) => form.setValue("isActive", checked ? "Y" : "N")}
                disabled={isLoading}
                aria-label="활성 상태"
              />
              <Label htmlFor="isActive" className="text-xs sm:text-sm">{form.watch("isActive") === "Y" ? "활성" : "비활성"}</Label>
            </div>
          )}

          {/* 버튼 */}
          <div className="flex gap-2 pt-4 sm:justify-end sm:gap-0">
            <Button 
              type="button" 
              variant="outline" 
              onClick={onClose} 
              disabled={isLoading}
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
            >
              취소
            </Button>
            <Button
              type="submit"
              disabled={isLoading || !form.formState.isValid || hasDuplicateErrors || isDuplicateChecking}
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
            >
              {isLoading ? (
                <>
                  <LoadingSpinner size="sm" className="mr-2" />
                  {isEditing ? "수정 중..." : "저장 중..."}
                </>
              ) : isEditing ? (
                "코드 수정"
              ) : (
                "코드 저장"
              )}
            </Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  );
}
