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

function getReferenceImages(params: Record<string, unknown>) {
  const referenceImages = Array.isArray(params.referenceImages)
    ? params.referenceImages.filter((item): item is string => typeof item === 'string' && item.trim().length > 0)
    : [];
  const referenceImage = typeof params.referenceImage === 'string' && params.referenceImage.trim()
    ? params.referenceImage
    : referenceImages[0];
  return { referenceImage, referenceImages };
}

export async function GET(request: NextRequest) {
  const url = request.nextUrl.searchParams;
  const type = url.get('type');
  const limit = Math.min(parseInt(url.get('limit') || '50', 10), 300);
  const offset = parseInt(url.get('offset') || '0', 10);
  const sort = url.get('sort') || 'newest';
  const search = (url.get('q') || url.get('search') || '').trim().toLowerCase();

  try {
    const client = await getDbClient();

    try {
      const where: string[] = ['w.is_public = true', 'w.status = $1'];
      const params: unknown[] = ['completed'];

      if (type === 'image') {
        params.push('text2img', 'img2img');
        where.push(`w.type IN ($${params.length - 1}, $${params.length})`);
      } else if (type === 'video') {
        params.push('text2video', 'img2video');
        where.push(`w.type IN ($${params.length - 1}, $${params.length})`);
      }

      if (search) {
        params.push(`%${search}%`);
        const idx = params.length;
        where.push(`(
          LOWER(COALESCE(w.title, '')) LIKE $${idx}
          OR LOWER(COALESCE(w.prompt, '')) LIKE $${idx}
          OR LOWER(COALESCE(w.negative_prompt, '')) LIKE $${idx}
          OR LOWER(COALESCE(p.display_nickname, p.nickname, '')) LIKE $${idx}
          OR LOWER(COALESCE(p.nickname, '')) LIKE $${idx}
          OR LOWER(COALESCE(p.email, '')) LIKE $${idx}
          OR LOWER(COALESCE(w.params::text, '')) LIKE $${idx}
        )`);
      }

      let query = `
        SELECT w.id, w.type, w.title, w.prompt, w.negative_prompt, w.result_url, w.thumbnail_url,
               w.width, w.height, w.duration, w.is_public, w.likes_count, w.credits_cost,
               w.status, w.created_at, w.user_id, w.params,
               p.nickname, p.display_nickname, p.email, p.avatar_url
        FROM works w
        LEFT JOIN profiles p ON p.id = w.user_id
        WHERE ${where.join(' AND ')}
      `;

      if (sort === 'popular') {
        query += ' ORDER BY w.likes_count DESC, w.created_at DESC';
      } else {
        query += ' ORDER BY w.created_at DESC';
      }

      query += ` LIMIT ${limit} OFFSET ${offset}`;

      const result = await client.query(query, params);
      const countResult = await client.query(
        `SELECT COUNT(*) as total
         FROM works w
         LEFT JOIN profiles p ON p.id = w.user_id
         WHERE ${where.join(' AND ')}`,
        params,
      );

      const works = (result.rows || []).map((w: Record<string, unknown>) => {
        const workParams = (w.params || {}) as Record<string, unknown>;
        const references = getReferenceImages(workParams);
        return {
          id: w.id,
          type: w.type,
          title: w.title,
          prompt: w.prompt,
          negativePrompt: w.negative_prompt,
          url: w.result_url,
          thumbnailUrl: w.thumbnail_url,
          width: w.width,
          height: w.height,
          duration: w.duration,
          likes: w.likes_count || 0,
          creditsCost: w.credits_cost || 0,
          params: workParams,
          referenceImage: references.referenceImage,
          referenceImages: references.referenceImages,
          publisherId: w.user_id,
          publisherNickname: (w.display_nickname as string) || (w.nickname as string) || ((w.email as string) || '').split('@')[0] || '匿名用户',
          publisherAvatarUrl: (w.avatar_url as string | null) || null,
          publishedAt: w.created_at,
        };
      });

      return NextResponse.json({ works, total: parseInt(countResult.rows[0]?.total || '0', 10) });
    } finally {
      client.release();
    }
  } catch (err) {
    console.error('[gallery] GET error:', err);
    return NextResponse.json({ error: '获取作品列表失败' }, { status: 500 });
  }
}

export async function DELETE(request: NextRequest) {
  const authError = await requireAdmin(request);
  if (authError) return authError;

  try {
    const body = await request.json().catch(() => ({}));
    const searchId = request.nextUrl.searchParams.get('id');
    const bodyIds = Array.isArray(body.ids) ? body.ids : [];
    const ids = [...new Set([searchId, ...bodyIds].filter((id): id is string => typeof id === 'string' && id.trim().length > 0))];

    if (ids.length === 0) {
      return NextResponse.json({ error: '缺少要删除的作品 ID' }, { status: 400 });
    }
    if (ids.length > 100) {
      return NextResponse.json({ error: '单次最多删除 100 个画廊作品' }, { status: 400 });
    }

    const client = await getDbClient();
    try {
      const result = await client.query(
        `UPDATE works
         SET is_public = false
         WHERE id = ANY($1) AND is_public = true
         RETURNING id`,
        [ids],
      );
      return NextResponse.json({
        success: true,
        removed: result.rowCount || 0,
        ids: result.rows.map((row: Record<string, unknown>) => row.id),
      });
    } finally {
      client.release();
    }
  } catch (err) {
    console.error('[gallery] DELETE error:', err);
    return NextResponse.json({ error: '删除画廊作品失败' }, { status: 500 });
  }
}
