'use client';

import {
  useActionState,
  useEffect,
  useRef,
  useState,
  useTransition,
} 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 { openPostcodeSearch } from './postcode';
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 ?? '');
  const [isSearching, startSearching] = useTransition();

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

    // 칸별 오류는 해당 입력칸에 그대로 두고, 폼 전체에 걸린 사유만 토스트로 알린다 —
    // 긴 폼이라 맨 아래 문구는 스크롤 밖에 있으면 보이지 않는다.
    if (state.status === 'error' && state.message) {
      showToast({ variant: 'danger', message: state.message });
    }
  }, [state, showToast, onClose, isEdit]);

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

  /** 기획 ③ 주소 검색 연동 — 고른 주소로 우편번호·좌표까지 채운다. */
  function searchAddress() {
    startSearching(async () => {
      let picked;
      try {
        picked = await openPostcodeSearch();
      } catch {
        showToast({
          variant: 'danger',
          message: '주소 검색을 불러오지 못했습니다. 잠시 후 다시 시도해 주세요.',
        });
        return;
      }

      if (!picked) {
        return;
      }

      setAddress(picked.address);
      setPostalCode(picked.zonecode);
      setLatitude(picked.latitude);
      setLongitude(picked.longitude);
    });
  }

  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={isSearching ? '검색 중...' : '주소 검색'}
              disabled={isSearching}
              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>
        )}
      </form>
    </FoxModal>
  );
}
