'use server';

import { redirect } from 'next/navigation';
import { revalidatePath } from 'next/cache';
import {
  requestAdminLogin,
  type DuplicateLoginNotice,
} from '@/lib/data/repositories/auth-repository';
import { createSession } from '@/lib/auth/session';
import { FORCE_LOGIN_FIELD } from '@/lib/constants/login';

export type LoginFormState = {
  error?: string;
  /** 다른 곳에 살아 있는 세션이 있어 확인이 필요하다. 화면이 안내 후 강제 로그인으로 재요청한다. */
  duplicate?: DuplicateLoginNotice;
};

const GENERIC_LOGIN_ERROR = '아이디 또는 비밀번호가 올바르지 않습니다.';
const MAX_LOGIN_ID_LENGTH = 100;
const MAX_PASSWORD_LENGTH = 200;

function readTrimmedField(formData: FormData, key: string): string | null {
  const value = formData.get(key);
  if (typeof value !== 'string') {
    return null;
  }

  const trimmed = value.trim();
  return trimmed.length > 0 ? trimmed : null;
}

/**
 * 로그인 Server Action — 인증의 진입점이라 사전 인증 확인은 성립하지 않는다(예외로 명시).
 */
export async function login(
  _prevState: LoginFormState,
  formData: FormData
): Promise<LoginFormState> {
  const loginId = readTrimmedField(formData, 'loginId');
  const password = readTrimmedField(formData, 'password');

  if (
    !loginId ||
    !password ||
    loginId.length > MAX_LOGIN_ID_LENGTH ||
    password.length > MAX_PASSWORD_LENGTH
  ) {
    return { error: GENERIC_LOGIN_ERROR };
  }

  const outcome = await requestAdminLogin({
    loginId,
    password,
    forceLogin: formData.get(FORCE_LOGIN_FIELD) === '1',
  });

  if (outcome.status === 'failure') {
    return { error: outcome.message };
  }

  if (outcome.status === 'duplicate') {
    return { duplicate: outcome.notice };
  }

  await createSession({
    userId: outcome.admin.id,
    loginId: outcome.admin.loginId,
    userNm: outcome.admin.name,
    roleId: outcome.admin.roleCode,
    accessToken: outcome.accessToken,
    refreshToken: outcome.refreshToken,
    exp: outcome.accessTokenExpiresAt,
  });
  revalidatePath('/', 'layout');
  redirect('/');
}
