import type { Response } from 'express';
import { Logger } from '@nestjs/common';
import { Prisma } from '@prisma/client';
import { MeetingAttendanceError } from './meeting-attendance.error';

const defaultLogger = new Logger('MeetingAttendanceError');
const loggerCache = new Map<string, Logger>();

function getLogger(name?: string): Logger {
  if (!name || name === 'MeetingAttendanceError') return defaultLogger;
  let cached = loggerCache.get(name);
  if (!cached) {
    cached = new Logger(name);
    loggerCache.set(name, cached);
  }
  return cached;
}

/**
 * meeting-attendance 模块控制器统一 error 兜底。
 *
 * 替代各 controller 内零碎的 `private handleError(...)`，统一行为：
 *
 *   1. MeetingAttendanceError —— 业务自定义，按 status + message + (可选) code 返回。
 *   2. Prisma P2023（uuid 字段收到非法字符串）—— 400 Invalid id format。
 *      触发场景：`:id` 路径参数不是合法 UUID，直接落到 `findUnique({ where: { id } })`。
 *      详见 issue #463 / .learnings/ERRORS/ERR-20260519-008。
 *   3. Prisma P2025（update / delete 找不到记录）—— 404 Record not found。
 *   4. 其它 —— 落 error.stack 到 NestJS Logger 后，500 + fallbackMessage 返客户端。
 *
 * `loggerName` 可选 — 传入则用该名建/复用 Logger（按 controller 切日志保留模块粒度，
 * 跟原 reports/meetings/outlook-sync 各自 createLogger 行为对齐）；不传默认走
 * 'MeetingAttendanceError' 统一标签。Logger 实例按 name 缓存避免每次 catch 都 new。
 */
export function handleMeetingAttendanceError(
  res: Response,
  error: unknown,
  fallbackMessage: string,
  loggerName?: string,
): Response {
  if (error instanceof MeetingAttendanceError) {
    const body: Record<string, unknown> = { error: error.message };
    if (error.code) body.code = error.code;
    return res.status(error.status).json(body);
  }

  if (error instanceof Prisma.PrismaClientKnownRequestError) {
    if (error.code === 'P2023') {
      return res.status(400).json({ error: 'Invalid id format' });
    }
    if (error.code === 'P2025') {
      return res.status(404).json({ error: 'Record not found' });
    }
  }

  const logger = getLogger(loggerName);
  if (error instanceof Error) {
    logger.error(error.message, error.stack);
  } else {
    logger.error(`Unhandled non-Error thrown: ${JSON.stringify(error)}`);
  }

  return res.status(500).json({ error: fallbackMessage || 'Server error' });
}
