'use server';

import { revalidatePath } from 'next/cache';
import { redirect, unstable_rethrow } from 'next/navigation';
import { verifySession } from '@/lib/auth/dal';
import { BackendRequestError } from '@/lib/http/backend-fetch';
import {
  createBannedWord,
  deleteBannedWord,
  uploadBannedWordExcel,
} from '@/lib/data/repositories/banned-word-repository';
import {
  DUPLICATE_WORD_MESSAGE,
  validateBannedWord,
  type BannedWordFormState,
  type ExcelUploadResult,
} from '@/lib/domain/banned-word-form';
import { BANNED_WORDS_PATH } from '@/lib/domain/banned-word-query';

const SAVE_FAILED_MESSAGE = '등록하지 못했습니다. 잠시 후 다시 시도해 주세요.';
const DELETE_FAILED_MESSAGE = '삭제하지 못했습니다. 잠시 후 다시 시도해 주세요.';
const UPLOAD_FAILED_MESSAGE =
  '엑셀 파일을 등록하지 못했습니다. 잠시 후 다시 시도해 주세요.';

function failureMessage(error: unknown, fallback: string): string {
  return error instanceof BackendRequestError ? error.message : fallback;
}

function readString(formData: FormData, key: string): string {
  const value = formData.get(key);
  return typeof value === 'string' ? value : '';
}

/** 기획 SYS_WRD_002 ② — 등록이 끝나면 목록으로 돌아간다. */
export async function createBannedWordAction(
  _prevState: BannedWordFormState,
  formData: FormData
): Promise<BannedWordFormState> {
  await verifySession();

  const validation = validateBannedWord(readString(formData, 'word'));
  if (!validation.ok) {
    return { status: 'error', errors: validation.errors };
  }

  let result;
  try {
    result = await createBannedWord(validation.value);
  } catch (error) {
    // 이슈: 세션이 밀렸을 때 backendFetch가 던지는 redirect를 이 catch가 삼키면 안 된다.
    unstable_rethrow(error);
    return { status: 'error', message: failureMessage(error, SAVE_FAILED_MESSAGE) };
  }

  if (result.status === 'duplicate') {
    return { status: 'error', errors: { word: DUPLICATE_WORD_MESSAGE } };
  }

  revalidatePath(BANNED_WORDS_PATH);
  redirect(BANNED_WORDS_PATH);
}

export async function deleteBannedWordAction(
  id: number
): Promise<{ status: 'success' } | { status: 'error'; message: string }> {
  await verifySession();

  try {
    await deleteBannedWord(id);
  } catch (error) {
    unstable_rethrow(error);
    return { status: 'error', message: failureMessage(error, DELETE_FAILED_MESSAGE) };
  }

  revalidatePath(BANNED_WORDS_PATH);
  return { status: 'success' };
}

export async function uploadBannedWordExcelAction(
  formData: FormData
): Promise<
  | { status: 'success'; result: ExcelUploadResult }
  | { status: 'error'; message: string }
> {
  await verifySession();

  const file = formData.get('file');
  if (!(file instanceof File) || file.size === 0) {
    return { status: 'error', message: '엑셀 파일을 첨부해 주세요.' };
  }

  let result: ExcelUploadResult;
  try {
    result = await uploadBannedWordExcel(file);
  } catch (error) {
    unstable_rethrow(error);
    return { status: 'error', message: failureMessage(error, UPLOAD_FAILED_MESSAGE) };
  }

  revalidatePath(BANNED_WORDS_PATH);
  return { status: 'success', result };
}
