import { NextRequest, NextResponse } from 'next/server';
import { getDbClient } from '@/storage/database/local-db';
import { getAuthenticatedUserId } from '@/lib/session-auth';

function toWorkType(type: string, params: Record<string, unknown>): string {
  const explicitMode = params.creationMode || params.workType || params.mode;
  if (explicitMode === 'text2img' || explicitMode === 'img2img' || explicitMode === 'text2video' || explicitMode === 'img2video' || explicitMode === 'reverse-prompt') {
    return explicitMode;
  }
  if (type === 'reverse-prompt') return 'reverse-prompt';
  const hasReference = Boolean(params.referenceImage)
    || (Array.isArray(params.referenceImages) && params.referenceImages.length > 0)
    || Number(params.refImageCount || 0) > 0;
  if (type === 'video') return hasReference ? 'img2video' : 'text2video';
  return hasReference ? 'img2img' : 'text2img';
}

function fromWorkType(type: string): 'image' | 'video' | 'reverse-prompt' {
  if (type === 'reverse-prompt') return 'reverse-prompt';
  return type.includes('video') ? 'video' : 'image';
}

function mapWork(row: Record<string, unknown>) {
  const params = (row.params || {}) as Record<string, unknown>;
  return {
    id: row.id,
    type: fromWorkType(String(row.type || 'text2img')),
    url: row.result_url,
    prompt: row.prompt || '',
    negativePrompt: row.negative_prompt || undefined,
    model: params.model || '',
    modelLabel: params.modelLabel || params.model || '',
    isCustomModel: Boolean(params.isCustomModel),
    params,
    referenceImage: params.referenceImage,
    referenceImages: Array.isArray(params.referenceImages)
      ? params.referenceImages
      : params.referenceImage
        ? [params.referenceImage]
        : undefined,
    published: row.is_public === true,
    createdAt: row.created_at,
  };
}

export async function GET(request: NextRequest) {
  const userId = await getAuthenticatedUserId(request);
  if (!userId) return NextResponse.json({ error: '请先登录' }, { status: 401 });
  const client = await getDbClient();
  try {
    const result = await client.query(
      `SELECT id, type, prompt, negative_prompt, params, result_url, is_public, status, created_at
       FROM works
       WHERE user_id = $1 AND status = 'completed'
       ORDER BY created_at DESC
       LIMIT 300`,
      [userId],
    );
    return NextResponse.json({ records: result.rows.map(mapWork) });
  } finally {
    client.release();
  }
}

export async function POST(request: NextRequest) {
  const userId = await getAuthenticatedUserId(request);
  if (!userId) return NextResponse.json({ error: '请先登录' }, { status: 401 });
  const body = await request.json();
  const records = Array.isArray(body.records) ? body.records : [body];
  const client = await getDbClient();
  try {
    await client.query('BEGIN');
    const saved = [];
    for (const record of records) {
      const params = {
        ...(record.params || {}),
        model: record.model || (record.params || {}).model,
        modelLabel: record.modelLabel || (record.params || {}).modelLabel,
        isCustomModel: Boolean(record.isCustomModel),
        referenceImage: record.referenceImage || (record.params || {}).referenceImage,
        referenceImages: record.referenceImages || (record.params || {}).referenceImages,
      };
      const workType = toWorkType(String(record.type || 'image'), params);
      let url = String(record.url || '').trim();
      if (workType === 'reverse-prompt') {
        url = url && !url.startsWith('data:') ? url : `[reverse-prompt:${record.id || Date.now()}]`;
      }
      if (!url || url.startsWith('data:')) continue;
      const existing = await client.query(
        `SELECT id, type, prompt, negative_prompt, params, result_url, is_public, status, created_at
         FROM works
         WHERE user_id = $1 AND result_url = $2
         LIMIT 1`,
        [userId, url],
      );
      if (existing.rows[0]) {
        saved.push(mapWork(existing.rows[0]));
        continue;
      }
      const result = await client.query(
        `INSERT INTO works (user_id, type, prompt, negative_prompt, params, result_url, is_public, status, credits_cost, created_at)
         VALUES ($1, $2, $3, $4, $5::jsonb, $6, $7, 'completed', $8, COALESCE($9::timestamptz, NOW()))
         RETURNING id, type, prompt, negative_prompt, params, result_url, is_public, status, created_at`,
        [
          userId,
          workType,
          record.prompt || '',
          record.negativePrompt || null,
          JSON.stringify(params),
          url,
          Boolean(record.published),
          Number(record.creditsCost || 0),
          record.createdAt || null,
        ],
      );
      if (result.rows[0]) saved.push(mapWork(result.rows[0]));
    }
    await client.query('COMMIT');
    return NextResponse.json({ records: saved });
  } catch (error) {
    await client.query('ROLLBACK');
    throw error;
  } finally {
    client.release();
  }
}

export async function DELETE(request: NextRequest) {
  const userId = await getAuthenticatedUserId(request);
  if (!userId) return NextResponse.json({ error: '请先登录' }, { status: 401 });
  const id = request.nextUrl.searchParams.get('id');
  const client = await getDbClient();
  try {
    if (id) {
      await client.query('DELETE FROM works WHERE id = $1 AND user_id = $2', [id, userId]);
    } else {
      await client.query('DELETE FROM works WHERE user_id = $1', [userId]);
    }
    return NextResponse.json({ success: true });
  } finally {
    client.release();
  }
}
