export const NAME_MAX_LENGTH = 100;
export const URL_MAX_LENGTH = 300;
export const SORT_ORDER_MAX = 9999;

export interface SystemMenuValues {
  id: string;
  parentId: string;
  parentIdPath: string;
  name: string;
  sortOrder: number;
  isTopActive: boolean;
  url: string;
  largeIconId: string;
  smallIconId: string;
  isActive: boolean;
}

export type SystemMenuFormErrors = Partial<
  Record<
    'name' | 'sortOrder' | 'url' | 'largeIconId' | 'smallIconId',
    string
  >
>;

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

export const INITIAL_SYSTEM_MENU_FORM_STATE: SystemMenuFormState = {
  status: 'idle',
};

/** 기획 SYS_MNU_002_p ④ — 미입력 시 이 문구를 띄운다. */
export const REQUIRED_MESSAGE = '필수입력 사항을 입력하세요.';

type ValidationResult =
  | { ok: true; values: SystemMenuValues }
  | { ok: false; errors: SystemMenuFormErrors };

function validateText(
  raw: string,
  max: number,
  label: string
): { value: string; error?: string } {
  const value = raw.trim();

  if (!value) {
    return { value, error: REQUIRED_MESSAGE };
  }
  if (value.length > max) {
    return { value, error: `${label}은 ${max}자 이내로 입력해 주세요.` };
  }
  return { value };
}

export function validateSystemMenu(values: SystemMenuValues): ValidationResult {
  const errors: SystemMenuFormErrors = {};

  const name = validateText(values.name, NAME_MAX_LENGTH, '메뉴명');
  if (name.error) {
    errors.name = name.error;
  }

  const url = validateText(values.url, URL_MAX_LENGTH, '메뉴링크');
  if (url.error) {
    errors.url = url.error;
  }

  if (!Number.isInteger(values.sortOrder) || values.sortOrder < 1) {
    errors.sortOrder = '메뉴순번은 1 이상의 숫자로 입력해 주세요.';
  } else if (values.sortOrder > SORT_ORDER_MAX) {
    errors.sortOrder = `메뉴순번은 ${SORT_ORDER_MAX} 이하로 입력해 주세요.`;
  }

  if (Object.keys(errors).length > 0) {
    return { ok: false, errors };
  }

  return {
    ok: true,
    values: {
      ...values,
      name: name.value,
      url: url.value,
    },
  };
}
