'use client';

import { useActionState, useEffect, useState, useTransition } from 'react';
import { Button } from '@/components/ui/button';
import { Field } from '@/components/ui/field';
import { Input } from '@/components/ui/input';
import { Modal } from '@/components/ui/modal';
import { useFeedback } from '@/app/_hooks/use-feedback';
import {
  ADMIN_LOGIN_ID_HELP_TEXT,
  ADMIN_PASSWORD_HELP_TEXT,
  INITIAL_ADMIN_MEMBER_FORM_STATE,
} from '@/lib/domain/admin-member-form';
import {
  checkAdminLoginId,
  createAdminMemberAction,
  type LoginIdCheckResult,
} from '../_actions';
import {
  AdminMemberFormFields,
  FieldError,
} from './admin-member-form-fields';

interface AdminMemberCreateModalProps {
  onClose: () => void;
}

const FORM_ID = 'admin-member-create-form';

/**
 * 관리자 등록 팝업(시안 ADM_ADM_102_p).
 *
 * **ID는 중복 확인을 통과해야 저장할 수 있다**(시안 ①). 확인은 등록 폼과 별개의 서버 호출인데,
 * 폼 안에 폼을 중첩할 수 없어 `useActionState` 대신 값을 직접 넘기는 Server Action
 * (`checkAdminLoginId`)을 `useTransition`으로 호출한다. 확인 후 사용자가 ID를 고칠 수 있으므로
 * "확인에 성공한 ID"와 "지금 입력창의 값"이 같을 때만 통과로 본다 — 확인만 받아 두고 다른 ID로
 * 바꿔 저장하는 경로를 막기 위해서다. 그래도 최종 방어선은 Server Action의 재확인이다.
 *
 * 저장 버튼은 footer 슬롯에서 `form={FORM_ID}` 속성으로 폼과 연결한다 — 네이티브 HTML의 `form`
 * 속성은 버튼이 실제 DOM상 form의 자손이 아니어도 같은 문서 안에서 id만 일치하면 그 form을
 * 제출한다.
 *
 * 비밀번호는 형식만 검증하고 저장되지 않는다 — 백엔드에 등록 API가 없어 지금은 mock 저장소가
 * 받는데, 평문 비밀번호를 메모리에 들고 있지 않기로 했기 때문이다(Repository·mock 주석 참조).
 */
export function AdminMemberCreateModal({
  onClose,
}: AdminMemberCreateModalProps) {
  const { showToast } = useFeedback();
  const [state, formAction, isPending] = useActionState(
    createAdminMemberAction,
    INITIAL_ADMIN_MEMBER_FORM_STATE
  );

  const [loginId, setLoginId] = useState('');
  const [checkResult, setCheckResult] = useState<LoginIdCheckResult>({
    status: 'idle',
  });
  const [isChecking, startChecking] = useTransition();

  useEffect(() => {
    if (state.status === 'success') {
      showToast({ variant: 'success', message: '관리자를 등록했습니다.' });
      onClose();
    }
  }, [state, showToast, onClose]);

  const isLoginIdVerified =
    checkResult.status === 'available' &&
    checkResult.loginId === loginId.trim();

  function handleCheckLoginId() {
    startChecking(async () => {
      setCheckResult(await checkAdminLoginId(loginId));
    });
  }

  const errors = state.status === 'error' ? (state.errors ?? {}) : {};

  return (
    <Modal
      title="관리자 등록"
      onClose={onClose}
      footer={
        <>
          <Button type="button" variant="ghost" onClick={onClose}>
            취소
          </Button>
          <Button
            type="submit"
            form={FORM_ID}
            variant="primary"
            disabled={isPending || !isLoginIdVerified}
            title={isLoginIdVerified ? undefined : 'ID 중복 확인이 필요합니다.'}
          >
            {isPending ? '저장 중...' : '저장'}
          </Button>
        </>
      }
    >
      <form id={FORM_ID} action={formAction} className="flex flex-col gap-4">
        <p className="text-right text-body-sm text-danger">
          * 는 필수 항목입니다.
        </p>

        <Field label="이름 *">
          <Input type="text" name="name" placeholder="이름을 입력하세요." />
        </Field>
        <FieldError message={errors.name} />

        <Field label="ID * (중복확인 필수)">
          <div className="flex items-center gap-2">
            <Input
              type="text"
              name="loginId"
              value={loginId}
              onChange={(event) => setLoginId(event.target.value)}
              placeholder="관리자 ID를 입력하세요."
              autoComplete="off"
            />
            <Button
              type="button"
              variant="secondary"
              onClick={handleCheckLoginId}
              disabled={isChecking || loginId.trim().length === 0}
              className="shrink-0"
            >
              {isChecking ? '확인 중...' : '중복 확인'}
            </Button>
          </div>
        </Field>
        <p className="text-body-sm text-foreground-muted">
          {ADMIN_LOGIN_ID_HELP_TEXT}
        </p>
        {checkResult.status === 'unavailable' && (
          <FieldError message={checkResult.message} />
        )}
        {isLoginIdVerified && (
          <p className="text-body-sm text-success">사용할 수 있는 ID입니다.</p>
        )}
        <FieldError message={errors.loginId} />

        <Field label="비밀번호 *">
          <Input
            type="password"
            name="password"
            placeholder="비밀번호를 입력하세요."
            autoComplete="new-password"
          />
        </Field>
        <p className="text-body-sm text-foreground-muted">
          {ADMIN_PASSWORD_HELP_TEXT}
        </p>
        <FieldError message={errors.password} />

        <AdminMemberFormFields errors={errors} />

        {state.status === 'error' && state.message && (
          <p className="text-body-sm text-danger">{state.message}</p>
        )}
      </form>
    </Modal>
  );
}
