"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[];
  defaultParentCode?: string; // 하위 코드 추가 시 기본 부모 코드
}

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

// 코드값 자동 생성 함수 (UUID 기반 짧은 코드)
const generateCodeValue = (): string => {
  const timestamp = Date.now().toString(36).toUpperCase();
  const random = Math.random().toString(36).substring(2, 6).toUpperCase();
  return `${timestamp}${random}`;
};

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

  const isEditing = !!editingCode;

  // 검증 상태 관리 (코드명만 중복 검사)
  const [validationStates, setValidationStates] = useState({
    codeName: { enabled: false, value: "" },
  });

  // 코드명 중복 검사
  const codeNameCheck = useCheckCodeDuplicate(
    categoryCode,
    "codeName",
    validationStates.codeName.value,
    isEditing ? editingCode?.codeValue || editingCode?.code_value : undefined,
    validationStates.codeName.enabled,
  );

  // 중복 검사 결과 확인
  const hasDuplicateErrors = codeNameCheck.data?.isDuplicate && validationStates.codeName.enabled;

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

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

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

  // 편집 모드일 때 기존 데이터 로드
  useEffect(() => {
    if (isOpen) {
      if (isEditing && editingCode) {
        // 수정 모드: 기존 데이터 로드 (codeValue는 표시용으로만 설정)
        const parentValue = editingCode.parentCodeValue || editingCode.parent_code_value || "";

        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",
          parentCodeValue: parentValue,
        });

        // 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)) : 0;

        // 기본 부모 코드가 있으면 설정 (하위 코드 추가 시)
        const parentValue = defaultParentCode || "";

        // 코드값 자동 생성
        const autoCodeValue = generateCodeValue();

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

  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 ? "코드 수정" : defaultParentCode ? "하위 코드 추가" : "새 코드"}
          </DialogTitle>
        </DialogHeader>

        <form onSubmit={handleSubmit} className="space-y-3 sm:space-y-4">
          {/* 코드값 (자동 생성, 수정 시에만 표시) */}
          {isEditing && (
            <div className="space-y-2">
              <Label className="text-xs sm:text-sm">코드값</Label>
              <div className="bg-muted h-8 rounded-md border px-3 py-1.5 text-xs sm:h-10 sm:py-2 sm:text-sm">
                {form.watch("codeValue")}
              </div>
              <p className="text-muted-foreground text-[10px] sm:text-xs">코드값은 변경할 수 없습니다</p>
            </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
                  ? "border-destructive h-8 text-xs sm:h-10 sm:text-sm"
                  : "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-destructive text-[10px] sm:text-xs">
                {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="h-8 text-xs sm:h-10 sm:text-sm"
            />
          </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={2}
              className="text-xs sm:text-sm"
            />
          </div>

          {/* 부모 코드 표시 (하위 코드 추가 시에만 표시, 읽기 전용) */}
          {defaultParentCode && (
            <div className="space-y-2">
              <Label className="text-xs sm:text-sm">상위 코드</Label>
              <div className="bg-muted h-8 rounded-md border px-3 py-1.5 text-xs sm:h-10 sm:py-2 sm:text-sm">
                {(() => {
                  const parentCode = codes.find((c) => (c.codeValue || c.code_value) === defaultParentCode);
                  return parentCode
                    ? `${parentCode.codeName || parentCode.code_name} (${defaultParentCode})`
                    : defaultParentCode;
                })()}
              </div>
              <p className="text-muted-foreground text-[10px] sm:text-xs">이 코드는 위 코드의 하위로 추가됩니다</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
                  ? "border-destructive h-8 text-xs sm:h-10 sm:text-sm"
                  : "h-8 text-xs sm:h-10 sm:text-sm"
              }
            />
            {form.formState.errors.sortOrder && (
              <p className="text-destructive text-[10px] sm:text-xs">
                {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>
  );
}
