import { NextResponse } from 'next/server';
import type { RowDataPacket } from 'mysql2';

import { requireAdminApi } from '@/lib/auth/apiAuth';
import { getPool } from '@/lib/db';

export const dynamic = 'force-dynamic';

type Ctx = { params: Promise<{ id: string }> };

export async function GET(_request: Request, context: Ctx) {
  const auth = await requireAdminApi();
  if (!auth.ok) {
    return auth.response;
  }

  const { id: idParam } = await context.params;
  const id = parseInt(idParam, 10);
  if (Number.isNaN(id)) {
    return NextResponse.json({ error: 'Invalid id' }, { status: 400 });
  }

  const pool = getPool();
  const [rows] = await pool.query<RowDataPacket[]>(
    `SELECT p.id, p.player_key, p.player_name, p.description, p.image, p.character_id,
            c.name_id, c.name, c.name_jp
     FROM players p
     LEFT JOIN characters c ON c.id = p.character_id
     WHERE p.id = ?`,
    [id]
  );

  if (rows.length === 0) {
    return NextResponse.json({ error: 'Not found' }, { status: 404 });
  }

  return NextResponse.json({ player: rows[0] });
}

export async function PATCH(request: Request, context: Ctx) {
  const auth = await requireAdminApi();
  if (!auth.ok) {
    return auth.response;
  }

  const { id: idParam } = await context.params;
  const id = parseInt(idParam, 10);
  if (Number.isNaN(id)) {
    return NextResponse.json({ error: 'Invalid id' }, { status: 400 });
  }

  const body = await request.json();
  const updates: string[] = [];
  const values: unknown[] = [];

  if (body.player_key !== undefined) {
    updates.push('player_key = ?');
    values.push(String(body.player_key).trim());
  }
  if (body.player_name !== undefined) {
    updates.push('player_name = ?');
    values.push(String(body.player_name).trim());
  }
  if (body.description !== undefined) {
    updates.push('description = ?');
    values.push(String(body.description));
  }
  if (body.image !== undefined) {
    updates.push('image = ?');
    values.push(body.image == null ? null : String(body.image));
  }
  if (body.character_id !== undefined) {
    updates.push('character_id = ?');
    values.push(String(parseInt(String(body.character_id), 10)));
  }

  if (updates.length === 0) {
    return NextResponse.json({ error: 'No fields to update' }, { status: 400 });
  }

  values.push(id);
  const pool = getPool();
  await pool.query(`UPDATE players SET ${updates.join(', ')} WHERE id = ?`, values);

  const [rows] = await pool.query<RowDataPacket[]>(
    `SELECT p.id, p.player_key, p.player_name, p.description, p.image, p.character_id,
            c.name_id, c.name, c.name_jp
     FROM players p
     LEFT JOIN characters c ON c.id = p.character_id
     WHERE p.id = ?`,
    [id]
  );

  return NextResponse.json({ player: rows[0] });
}

export async function DELETE(_request: Request, context: Ctx) {
  const auth = await requireAdminApi();
  if (!auth.ok) {
    return auth.response;
  }

  const { id: idParam } = await context.params;
  const id = parseInt(idParam, 10);
  if (Number.isNaN(id)) {
    return NextResponse.json({ error: 'Invalid id' }, { status: 400 });
  }

  const pool = getPool();
  try {
    await pool.query('DELETE FROM players WHERE id = ?', [id]);
  } catch (e: unknown) {
    const code = (e as { errno?: number })?.errno;
    if (code === 1451) {
      return NextResponse.json(
        { error: 'Cannot delete player: referenced by tournament or other records' },
        { status: 409 }
      );
    }
    throw e;
  }

  return NextResponse.json({ ok: true });
}
