import { NextRequest, NextResponse } from 'next/server';
import { requireAuth } from '@/lib/auth-utils';
import { postgresClient } from '@/lib/services/postgres-client';

// GET  /api/me/theme  -> { theme: 'light' | 'dark' | 'system', source: 'user' | 'default' }
// PUT  /api/me/theme  -> body { theme: 'light' | 'dark' | 'system' } -> { theme: string }
//
// THEME-02. Authentication: requireAuth(). The PUT handler updates ONLY the
// calling user's row — there is no `userId` query param or body field. The
// write target is always `session.user.id`.
//
// Validation: the input theme must be one of: 'light', 'dark', 'system'.
// Anything else is rejected with 400 before touching the database.
//
// NOTE: The UPDATE statement uses `"updatedAt"` (quoted camelCase) — that is
// the actual column name in the Better Auth `"user"` table (verified via psql).
// Matches the working precedent in app/api/me/timezone/route.ts.

const ALLOWED_THEMES = new Set(['light', 'dark', 'system'] as const);

function isValidTheme(t: unknown): t is 'light' | 'dark' | 'system' {
  return typeof t === 'string' && ALLOWED_THEMES.has(t as 'light' | 'dark' | 'system');
}

export async function GET(): Promise<NextResponse> {
  const { session, error } = await requireAuth();
  if (error) return error;

  try {
    const result = await postgresClient.query<{ theme: string | null }>(
      'SELECT theme FROM "user" WHERE id = $1',
      [session!.user.id],
    );
    const stored = result.rows[0]?.theme;
    // source is 'user' when a non-default value is explicitly stored;
    // 'default' when value equals fallback ('system') or no row found.
    const theme = stored ?? 'system';
    const source: 'user' | 'default' = stored && stored !== 'system' ? 'user' : 'default';
    return NextResponse.json({ theme, source });
  } catch (e) {
    console.error('GET /api/me/theme failed:', e);
    return NextResponse.json(
      { error: 'Failed to read theme', message: e instanceof Error ? e.message : 'unknown' },
      { status: 500 },
    );
  }
}

export async function PUT(request: NextRequest): Promise<NextResponse> {
  const { session, error } = await requireAuth();
  if (error) return error;

  let body: unknown;
  try {
    body = await request.json();
  } catch {
    return NextResponse.json(
      { error: 'Invalid JSON', message: 'Request body must be JSON' },
      { status: 400 },
    );
  }

  const candidate =
    body && typeof body === 'object' && 'theme' in body
      ? (body as { theme: unknown }).theme
      : undefined;

  if (!isValidTheme(candidate)) {
    return NextResponse.json(
      { error: 'Invalid theme', message: 'theme must be one of: light, dark, system' },
      { status: 400 },
    );
  }

  try {
    // Authoritative write target: session.user.id. NO userId from body.
    // "updatedAt" is quoted camelCase — matches Better Auth schema (verified).
    const result = await postgresClient.query<{ theme: string }>(
      'UPDATE "user" SET theme = $1, "updatedAt" = NOW() WHERE id = $2 RETURNING theme',
      [candidate, session!.user.id],
    );
    if (result.rowCount === 0) {
      return NextResponse.json(
        { error: 'User not found', message: 'No user row matched the session' },
        { status: 404 },
      );
    }
    return NextResponse.json({ theme: result.rows[0].theme });
  } catch (e) {
    console.error('PUT /api/me/theme failed:', e);
    return NextResponse.json(
      { error: 'Failed to update theme', message: e instanceof Error ? e.message : 'unknown' },
      { status: 500 },
    );
  }
}
