'use client';

import { useActionState, useEffect, useRef, useState } from 'react';
import { FoxButton } from '@fox/core/components/fox-button';
import { FoxFormLabel } from '@fox/core/components/fox-form-label';
import { FoxHelperText } from '@fox/core/components/fox-helper-text';
import { FoxInput } from '@fox/core/components/fox-input';
import { FoxModal } from '@fox/core/components/fox-modal';
import { FoxRadio } from '@fox/core/components/fox-radio';
import { FoxRadioGroup } from '@fox/core/components/fox-radio-group';
import { FoxSelect } from '@fox/core/components/fox-select';
import { submitFormAction } from '@/app/_hooks/submit-form-action';
import { useFeedback } from '@/app/_hooks/use-feedback';
import {
  MERCHANT_CATEGORY_OPTIONS,
  formatOptionalValue,
  type Merchant,
} from '@/lib/domain/merchant';
import {
  ADDRESS_DETAIL_MAX_LENGTH,
  BRAND_MAX_LENGTH,
  INITIAL_MERCHANT_FORM_STATE,
  MEMO_MAX_LENGTH,
  NAME_MAX_LENGTH,
  OWNER_MAX_LENGTH,
} from '@/lib/domain/merchant-form';
import { saveMerchantAction } from '../_actions';
import styles from './merchant-form.module.scss';

interface MerchantFormModalProps {
  merchant?: Merchant;
  onClose: () => void;
}

export function MerchantFormModal({ merchant, onClose }: MerchantFormModalProps) {
  const isEdit = Boolean(merchant);
  const { showToast } = useFeedback();
  const formRef = useRef<HTMLFormElement>(null);
  const [state, formAction, isPending] = useActionState(
    saveMerchantAction,
    INITIAL_MERCHANT_FORM_STATE
  );

  const [categoryCode, setCategoryCode] = useState(merchant?.categoryCode ?? '');
  const [isVisible, setIsVisible] = useState(merchant?.isVisible ?? true);
  // 주소·좌표는 검색 결과가 채운다(기획 ③ Read Only).
  const [address, setAddress] = useState(merchant?.address ?? '');
  const [postalCode, setPostalCode] = useState(merchant?.postalCode ?? '');
  const [latitude, setLatitude] = useState(merchant?.latitude ?? '');
  const [longitude, setLongitude] = useState(merchant?.longitude ?? '');

  useEffect(() => {
    if (state.status === 'success') {
      showToast({
        variant: 'success',
        message: isEdit ? '가맹점을 수정했습니다.' : '가맹점을 등록했습니다.',
      });
      onClose();
    }
  }, [state, showToast, onClose, isEdit]);

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

  // TODO(기획): 주소 검색 서비스가 정해지지 않았다. 연동 전까지 직접 입력으로 받는다.
  function searchAddress() {
    const picked = window.prompt('주소를 입력하세요.', address);
    if (picked === null) {
      return;
    }
    setAddress(picked.trim());
    setPostalCode('');
    setLatitude('');
    setLongitude('');
  }

  return (
    <FoxModal
      open
      size="md"
      title={isEdit ? '가맹점 수정' : '가맹점 등록'}
      onClose={onClose}
      actions={
        <>
          <FoxButton type="default" size="md" label="취소" onAction={onClose} />
          <FoxButton
            type="primary"
            size="md"
            label={isPending ? '저장 중...' : isEdit ? '수정' : '등록'}
            disabled={isPending}
            onAction={() => formRef.current?.requestSubmit()}
          />
        </>
      }
    >
      <form
        ref={formRef}
        onSubmit={(event) => submitFormAction(event, formAction)}
        className={styles.fields}
      >
        <input type="hidden" name="id" value={merchant?.id ?? ''} />
        <input type="hidden" name="categoryCode" value={categoryCode} />
        <input type="hidden" name="isVisible" value={isVisible ? 'Y' : 'N'} />
        <input type="hidden" name="address" value={address} />
        <input type="hidden" name="postalCode" value={postalCode} />
        <input type="hidden" name="latitude" value={latitude} />
        <input type="hidden" name="longitude" value={longitude} />

        {/* 등록 시에는 코드가 아직 없다 — 저장할 때 서버가 만든다. */}
        {isEdit && (
          <div className={styles.field}>
            <FoxInput
              size="md"
              label="가맹점코드"
              value={merchant?.code ?? ''}
              readOnly
              state="view"
            />
          </div>
        )}

        {/* 브랜드명·메모·등록일은 백엔드에 컬럼이 없어 저장되지 않는다. 기획 시안에 있는
            항목이라 화면에서는 지우지 않고, 값이 없으면 `-`로 보여준다(사용자 확정). */}
        <div className={styles.field}>
          <FoxInput
            size="md"
            name="brandName"
            label="브랜드명"
            defaultValue={merchant?.brandName ?? ''}
            placeholder="브랜드명을 입력하세요."
            maxLength={BRAND_MAX_LENGTH}
          />
        </div>

        <div className={styles.field}>
          <FoxInput
            size="md"
            name="name"
            label="가맹점명"
            requirement="required"
            defaultValue={merchant?.name ?? ''}
            placeholder="가맹점명을 입력하세요."
            maxLength={NAME_MAX_LENGTH}
            invalid={Boolean(errors.name)}
            message={errors.name}
          />
        </div>

        <div className={styles.field}>
          <FoxSelect
            size="md"
            label="업종"
            requirement="required"
            options={MERCHANT_CATEGORY_OPTIONS.map((option) => ({
              value: option.value,
              label: option.label,
            }))}
            value={categoryCode}
            onValueChange={setCategoryCode}
            placeholder="선택"
            error={Boolean(errors.categoryCode)}
            hint={errors.categoryCode}
          />
        </div>

        <div className={styles.field}>
          <div className={styles.pair}>
            <FoxInput
              size="md"
              name="businessNumber"
              label="사업자등록번호"
              defaultValue={merchant?.businessNumber ?? ''}
              placeholder="000-00-00000"
              invalid={Boolean(errors.businessNumber)}
              message={errors.businessNumber}
            />
            <FoxInput
              size="md"
              name="ownerName"
              label="대표자명"
              defaultValue={merchant?.ownerName ?? ''}
              placeholder="대표자명을 입력하세요."
              maxLength={OWNER_MAX_LENGTH}
            />
          </div>
        </div>

        <div className={styles.field}>
          <FoxInput
            size="md"
            name="phoneNumber"
            label="전화번호"
            requirement="required"
            defaultValue={merchant?.phoneNumber ?? ''}
            placeholder="가게 전화번호를 입력하세요."
            invalid={Boolean(errors.phoneNumber)}
            message={errors.phoneNumber}
          />
        </div>

        <div className={styles.field}>
          <FoxFormLabel as="span" requirement="required">
            주소
          </FoxFormLabel>
          <div className={styles.addressRow}>
            <FoxInput
              size="md"
              aria-label="주소"
              value={address}
              readOnly
              state="view"
              placeholder="주소 검색을 진행해주세요."
            />
            <FoxButton
              type="secondary"
              size="md"
              label="주소 검색"
              onAction={searchAddress}
            />
          </div>
          <FoxInput
            size="md"
            name="addressDetail"
            aria-label="상세주소"
            defaultValue={merchant?.addressDetail ?? ''}
            placeholder="상세주소를 입력하세요."
            maxLength={ADDRESS_DETAIL_MAX_LENGTH}
          />
          {errors.address && (
            <FoxHelperText type="danger" message={errors.address} />
          )}
        </div>

        <div className={styles.field}>
          <FoxFormLabel as="span">위도 / 경도</FoxFormLabel>
          <div className={styles.pair}>
            <FoxInput
              size="md"
              aria-label="위도"
              value={latitude}
              readOnly
              state="view"
              placeholder="주소 검색 시 자동 입력"
            />
            <FoxInput
              size="md"
              aria-label="경도"
              value={longitude}
              readOnly
              state="view"
              placeholder="주소 검색 시 자동 입력"
            />
          </div>
        </div>

        <div className={styles.field}>
          <FoxFormLabel as="span" requirement="required">
            사용여부
          </FoxFormLabel>
          <FoxRadioGroup name="visibility" size="md" label="사용여부">
            <FoxRadio
              value="Y"
              label="노출"
              checked={isVisible}
              onChange={() => setIsVisible(true)}
            />
            <FoxRadio
              value="N"
              label="미노출"
              checked={!isVisible}
              onChange={() => setIsVisible(false)}
            />
          </FoxRadioGroup>
        </div>

        <div className={styles.field}>
          <FoxInput
            size="md"
            name="memo"
            label="메모"
            defaultValue={merchant?.memo ?? ''}
            placeholder="관리자 메모 (사용자에게 노출되지 않음)"
            maxLength={MEMO_MAX_LENGTH}
          />
        </div>

        {isEdit && (
          <div className={styles.field}>
            <FoxFormLabel as="span">등록일 / 최종수정일</FoxFormLabel>
            <div className={styles.pair}>
              <FoxInput
                size="md"
                aria-label="등록일"
                value={formatOptionalValue(merchant?.createdAt)}
                readOnly
                state="view"
              />
              <FoxInput
                size="md"
                aria-label="최종수정일"
                value={formatOptionalValue(merchant?.updatedAt)}
                readOnly
                state="view"
              />
            </div>
          </div>
        )}

        {state.status === 'error' && state.message && (
          <FoxHelperText type="danger" message={state.message} />
        )}
      </form>
    </FoxModal>
  );
}
