"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 { useCreateCodeInfo, useUpdateCodeInfo } from "@/hooks/queries/useCodeInfo";
import { useCheckCodeInfoDuplicate } from "@/hooks/queries/useValidation";
import type { CodeInfo } from "@/types/commonCode";
import {
  createCodeInfoSchema,
  updateCodeInfoSchema,
  type CreateCodeInfoData,
  type UpdateCodeInfoData,
} from "@/lib/schemas/commonCode";

interface CodeInfoFormModalProps {
  isOpen: boolean;
  onClose: () => void;
  editingCodeInfo?: string;
  existingRows: CodeInfo[];
}

export function CodeInfoFormModal({
  isOpen,
  onClose,
  editingCodeInfo,
  existingRows,
}: CodeInfoFormModalProps) {
  const createMutation = useCreateCodeInfo();
  const updateMutation = useUpdateCodeInfo();

  const isEditing = !!editingCodeInfo;
  const editingRow = existingRows.find((r) => r.code_info === editingCodeInfo);

  const createForm = useForm<CreateCodeInfoData>({
    resolver: zodResolver(createCodeInfoSchema),
    mode: "onChange",
    defaultValues: {
      code_info: "",
      code_name: "",
      code_name_eng: "",
      description: "",
      sort_order: 0,
    },
  });

  const updateForm = useForm<UpdateCodeInfoData>({
    resolver: zodResolver(updateCodeInfoSchema),
    mode: "onChange",
    defaultValues: {
      code_name: "",
      code_name_eng: "",
      description: "",
      sort_order: 0,
      is_active: "Y",
    },
  });

  const [validatedFields, setValidatedFields] = useState<Set<string>>(new Set());
  const handleFieldBlur = (name: string) => {
    setValidatedFields((prev) => new Set(prev).add(name));
  };

  const codeCheck = useCheckCodeInfoDuplicate(
    "code_info",
    isEditing ? "" : createForm.watch("code_info"),
    isEditing ? editingCodeInfo : undefined,
    validatedFields.has("code_info"),
  );
  const nameCheck = useCheckCodeInfoDuplicate(
    "code_name",
    isEditing ? updateForm.watch("code_name") : createForm.watch("code_name"),
    isEditing ? editingCodeInfo : undefined,
    validatedFields.has("code_name"),
  );
  const nameEngCheck = useCheckCodeInfoDuplicate(
    "code_name_eng",
    isEditing
      ? updateForm.watch("code_name_eng") || ""
      : createForm.watch("code_name_eng") || "",
    isEditing ? editingCodeInfo : undefined,
    validatedFields.has("code_name_eng"),
  );

  const hasDuplicateErrors =
    (!isEditing && codeCheck.data?.isDuplicate && validatedFields.has("code_info")) ||
    (nameCheck.data?.isDuplicate && validatedFields.has("code_name")) ||
    (nameEngCheck.data?.isDuplicate && validatedFields.has("code_name_eng"));

  const isDuplicateChecking =
    (!isEditing && codeCheck.isLoading) || nameCheck.isLoading || nameEngCheck.isLoading;

  useEffect(() => {
    if (!isOpen) return;
    setValidatedFields(new Set());

    if (isEditing && editingRow) {
      updateForm.reset({
        code_name: editingRow.code_name,
        code_name_eng: editingRow.code_name_eng || "",
        description: editingRow.description || "",
        sort_order: editingRow.sort_order ?? 0,
        is_active: (editingRow.is_active as "Y" | "N") || "Y",
      });
    } else {
      const maxSort =
        existingRows.length > 0
          ? Math.max(...existingRows.map((r) => r.sort_order ?? 0))
          : 0;
      createForm.reset({
        code_info: "",
        code_name: "",
        code_name_eng: "",
        description: "",
        sort_order: maxSort + 1,
      });
    }
  }, [isOpen, isEditing, editingRow, existingRows]); // eslint-disable-line react-hooks/exhaustive-deps

  const handleSubmit = isEditing
    ? updateForm.handleSubmit(async (data) => {
        try {
          await updateMutation.mutateAsync({ codeInfo: editingCodeInfo!, data });
          onClose();
          updateForm.reset();
        } catch (error) {
          console.error("그룹 수정 실패:", error);
        }
      })
    : createForm.handleSubmit(async (data) => {
        try {
          await createMutation.mutateAsync(data);
          onClose();
          createForm.reset();
        } catch (error) {
          console.error("그룹 생성 실패:", error);
        }
      });

  const isLoading = createMutation.isPending || updateMutation.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">
          {/* 그룹 코드 (code_info) */}
          {!isEditing && (
            <div className="space-y-2">
              <Label htmlFor="code_info" className="text-xs sm:text-sm">
                그룹 코드 *
              </Label>
              <Input
                id="code_info"
                {...createForm.register("code_info")}
                disabled={isLoading}
                placeholder="예: STATUS, USER_ROLE"
                className={
                  createForm.formState.errors.code_info
                    ? "h-8 border-destructive text-xs sm:h-10 sm:text-sm"
                    : "h-8 text-xs sm:h-10 sm:text-sm"
                }
                onBlur={() => handleFieldBlur("code_info")}
              />
              {createForm.formState.errors.code_info && (
                <p className="text-[10px] sm:text-xs text-destructive">
                  {createForm.formState.errors.code_info.message}
                </p>
              )}
              {!createForm.formState.errors.code_info && (
                <ValidationMessage
                  message={codeCheck.data?.message}
                  isValid={!codeCheck.data?.isDuplicate}
                  isLoading={codeCheck.isLoading}
                />
              )}
            </div>
          )}

          {isEditing && editingRow && (
            <div className="space-y-2">
              <Label htmlFor="code_info_display" className="text-xs sm:text-sm">
                그룹 코드
              </Label>
              <Input
                id="code_info_display"
                value={editingRow.code_info}
                disabled
                className="h-8 cursor-not-allowed bg-muted text-xs sm:h-10 sm:text-sm"
              />
              <p className="text-[10px] sm:text-xs text-muted-foreground">
                그룹 코드는 수정할 수 없습니다.
              </p>
            </div>
          )}

          {/* 그룹명 */}
          <div className="space-y-2">
            <Label htmlFor="code_name">그룹명 *</Label>
            <Input
              id="code_name"
              {...(isEditing
                ? updateForm.register("code_name")
                : createForm.register("code_name"))}
              disabled={isLoading}
              placeholder="그룹명을 입력하세요"
              className={
                (isEditing
                  ? updateForm.formState.errors.code_name
                  : createForm.formState.errors.code_name)
                  ? "border-destructive"
                  : ""
              }
              onBlur={() => handleFieldBlur("code_name")}
            />
            {(isEditing
              ? updateForm.formState.errors.code_name
              : createForm.formState.errors.code_name) && (
              <p className="text-sm text-destructive">
                {
                  (isEditing
                    ? updateForm.formState.errors.code_name
                    : createForm.formState.errors.code_name
                  )?.message
                }
              </p>
            )}
            {!(isEditing
              ? updateForm.formState.errors.code_name
              : createForm.formState.errors.code_name) && (
              <ValidationMessage
                message={nameCheck.data?.message}
                isValid={!nameCheck.data?.isDuplicate}
                isLoading={nameCheck.isLoading}
              />
            )}
          </div>

          {/* 영문명 */}
          <div className="space-y-2">
            <Label htmlFor="code_name_eng">그룹 영문명</Label>
            <Input
              id="code_name_eng"
              {...(isEditing
                ? updateForm.register("code_name_eng")
                : createForm.register("code_name_eng"))}
              disabled={isLoading}
              placeholder="영문명을 입력하세요 (선택)"
              onBlur={() => handleFieldBlur("code_name_eng")}
            />
            {!(isEditing
              ? updateForm.formState.errors.code_name_eng
              : createForm.formState.errors.code_name_eng) && (
              <ValidationMessage
                message={nameEngCheck.data?.message}
                isValid={!nameEngCheck.data?.isDuplicate}
                isLoading={nameEngCheck.isLoading}
              />
            )}
          </div>

          {/* 설명 */}
          <div className="space-y-2">
            <Label htmlFor="description">설명</Label>
            <Textarea
              id="description"
              {...(isEditing
                ? updateForm.register("description")
                : createForm.register("description"))}
              disabled={isLoading}
              placeholder="설명을 입력하세요 (선택)"
              rows={3}
            />
          </div>

          {/* 정렬 순서 */}
          <div className="space-y-2">
            <Label htmlFor="sort_order">정렬 순서</Label>
            <Input
              id="sort_order"
              type="number"
              {...(isEditing
                ? updateForm.register("sort_order", { valueAsNumber: true })
                : createForm.register("sort_order", { valueAsNumber: true }))}
              disabled={isLoading}
              min={0}
            />
          </div>

          {/* 활성 상태 (수정 시) */}
          {isEditing && (
            <div className="flex items-center space-x-2">
              <Switch
                id="is_active"
                checked={updateForm.watch("is_active") === "Y"}
                onCheckedChange={(checked) =>
                  updateForm.setValue("is_active", checked ? "Y" : "N")
                }
                disabled={isLoading}
              />
              <Label htmlFor="is_active">
                {updateForm.watch("is_active") === "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 ||
                !(isEditing ? updateForm.formState.isValid : createForm.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>
  );
}
