import type { CommonCode } from '@/lib/domain/common-code';
import { MAX_PRODUCT_BADGES, type MerchantProductBadge } from '@/lib/domain/merchant-product';

/** 기획 BO-MAL-004 ② — 필수는 메뉴명·가격·노출 여부 셋. */
export const PRODUCT_NAME_MAX_LENGTH = 100;
/** 기획 BO-MAL-004 ⑤ [의사결정 필요] 잠정값 — 설명 최대 글자수. */
export const PRODUCT_DESCRIPTION_MAX_LENGTH = 120;
export const PRODUCT_PRICE_MAX = 99_999_999;
export const PRODUCT_SORT_ORDER_MAX = 9999;

export type MerchantProductValues = {
  frcsNo: string;
  name: string;
  price: number | null;
  description: string;
  badges: MerchantProductBadge[];
  isVisible: boolean;
  sortOrder: number | null;
  imageFileId: string;
};

export type MerchantProductFormErrors = Partial<
  Record<'name' | 'price' | 'description' | 'badges' | 'sortOrder' | 'image', string>
>;

export type MerchantProductFormState =
  | { status: 'idle' }
  | { status: 'error'; message?: string; errors?: MerchantProductFormErrors }
  | { status: 'success' };

export const INITIAL_MERCHANT_PRODUCT_FORM_STATE: MerchantProductFormState = {
  status: 'idle',
};

type ValidationResult =
  | { ok: true; values: MerchantProductValues }
  | { ok: false; errors: MerchantProductFormErrors };

export function validateMerchantProduct(
  values: MerchantProductValues,
  badgeCodes: readonly CommonCode[]
): ValidationResult {
  const errors: MerchantProductFormErrors = {};

  const name = values.name.trim();
  if (!name) {
    errors.name = '메뉴명을 입력해 주세요.';
  } else if (name.length > PRODUCT_NAME_MAX_LENGTH) {
    errors.name = `메뉴명은 ${PRODUCT_NAME_MAX_LENGTH}자 이내로 입력해 주세요.`;
  }

  if (
    values.price === null ||
    !Number.isInteger(values.price) ||
    values.price < 0 ||
    values.price > PRODUCT_PRICE_MAX
  ) {
    errors.price = '가격은 숫자만 입력해 주세요.';
  }

  const description = values.description.trim();
  if (description.length > PRODUCT_DESCRIPTION_MAX_LENGTH) {
    errors.description = `설명은 ${PRODUCT_DESCRIPTION_MAX_LENGTH}자 이내로 입력해 주세요.`;
  }

  const badges = values.badges.filter((badge) => badgeCodes.some((code) => code.code === badge));
  if (badges.length > MAX_PRODUCT_BADGES) {
    errors.badges = `배지는 최대 ${MAX_PRODUCT_BADGES}개까지 고를 수 있습니다.`;
  }

  if (
    values.sortOrder !== null &&
    (!Number.isInteger(values.sortOrder) ||
      values.sortOrder < 0 ||
      values.sortOrder > PRODUCT_SORT_ORDER_MAX)
  ) {
    errors.sortOrder = `노출 순서는 0 이상 ${PRODUCT_SORT_ORDER_MAX} 이하의 숫자로 입력해 주세요.`;
  }

  if (Object.keys(errors).length > 0) {
    return { ok: false, errors };
  }
  return { ok: true, values: { ...values, name, description, badges } };
}
