import {
  foxValidationMessage,
  foxValidators,
  type FoxValidationMessages,
} from '@fox/core/validation';

export type AdminMenuValues = {
  name: string;
  sortOrder: number;
  roleId: string;
  isTopActive: boolean;
  url: string;
  /** 이슈: 백엔드에 대응 컬럼이 없어 저장되지 않는다. 기획대로 화면에만 둔다. */
  opensNewWindow: boolean;
  description: string;
  isActive: boolean;
};

export type AdminMenuFormErrors = Partial<Record<keyof AdminMenuValues, string>>;

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

export const INITIAL_ADMIN_MENU_FORM_STATE: AdminMenuFormState = {
  status: 'idle',
};

const NAME_MAX_LENGTH = 100;
const URL_MAX_LENGTH = 300;
const DESCRIPTION_MAX_LENGTH = 500;

const NAME_VALIDATORS = [
  foxValidators.required,
  foxValidators.maxLength(NAME_MAX_LENGTH),
];
const URL_VALIDATORS = [
  foxValidators.required,
  foxValidators.maxLength(URL_MAX_LENGTH),
];
const DESCRIPTION_VALIDATORS = [
  foxValidators.required,
  foxValidators.maxLength(DESCRIPTION_MAX_LENGTH),
];

export const ADMIN_MENU_NAME_MESSAGES: FoxValidationMessages = {
  required: '메뉴명을 입력해 주세요.',
  maxlength: `메뉴명은 ${NAME_MAX_LENGTH}자 이내로 입력해 주세요.`,
};
export const ADMIN_MENU_URL_MESSAGES: FoxValidationMessages = {
  required: '메뉴링크를 입력해 주세요.',
  maxlength: `메뉴링크는 ${URL_MAX_LENGTH}자 이내로 입력해 주세요.`,
};
export const ADMIN_MENU_DESCRIPTION_MESSAGES: FoxValidationMessages = {
  required: '메뉴설명을 입력해 주세요.',
  maxlength: `메뉴설명은 ${DESCRIPTION_MAX_LENGTH}자 이내로 입력해 주세요.`,
};

export { NAME_VALIDATORS, URL_VALIDATORS, DESCRIPTION_VALIDATORS };

function check(
  value: string,
  validators: typeof NAME_VALIDATORS,
  messages: FoxValidationMessages
): string | undefined {
  return foxValidationMessage(
    foxValidators.compose(validators)(value.trim()),
    messages
  );
}

export function validateAdminMenu(
  values: AdminMenuValues,
  allowedRoleIds: string[]
):
  | { ok: true; values: AdminMenuValues }
  | { ok: false; errors: AdminMenuFormErrors } {
  const errors: AdminMenuFormErrors = {};

  const name = values.name.trim();
  const url = values.url.trim();
  const description = values.description.trim();

  errors.name = check(name, NAME_VALIDATORS, ADMIN_MENU_NAME_MESSAGES);
  errors.url = check(url, URL_VALIDATORS, ADMIN_MENU_URL_MESSAGES);
  errors.description = check(
    description,
    DESCRIPTION_VALIDATORS,
    ADMIN_MENU_DESCRIPTION_MESSAGES
  );

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

  if (!allowedRoleIds.includes(values.roleId)) {
    errors.roleId = '메뉴권한을 선택해 주세요.';
  }

  for (const key of Object.keys(errors) as (keyof AdminMenuFormErrors)[]) {
    if (errors[key] === undefined) {
      delete errors[key];
    }
  }

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

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