// API Routes for Individual Report
import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/db';
import { generateReport, generateHTMLReport, generateCSV } from '@/lib/reports/report-generator';
import type { ReportColumn } from '@/lib/reports/report-definitions';

export const dynamic = 'force-dynamic';

interface RouteParams {
  params: Promise<{ reportId: string }>;
}

// GET - Get report definition or generate report
export async function GET(request: NextRequest, { params }: RouteParams) {
  try {
    const { reportId } = await params;
    const { searchParams } = new URL(request.url);
    const action = searchParams.get('action') || 'definition';

    // Fetch report by ID or key
    const report = await prisma.reportDefinition.findFirst({
      where: {
        OR: [{ id: reportId }, { key: reportId }],
      },
      include: {
        schedules: { where: { isEnabled: true } },
        _count: {
          select: {
            subscriptions: { where: { isActive: true } },
            generatedReports: true,
          },
        },
      },
    });

    if (!report) {
      return NextResponse.json(
        { error: 'Report not found' },
        { status: 404 }
      );
    }

    if (action === 'definition') {
      return NextResponse.json({ report });
    }

    if (action === 'generate') {
      // Parse filters from query params
      const filters: Record<string, unknown> = {};
      searchParams.forEach((value, key) => {
        if (key !== 'action' && key !== 'format') {
          try {
            filters[key] = JSON.parse(value);
          } catch {
            filters[key] = value;
          }
        }
      });

      const format = searchParams.get('format') || 'json';
      const sortBy = searchParams.get('sortBy') || undefined;
      const sortOrder = (searchParams.get('sortOrder') || 'asc') as 'asc' | 'desc';
      const page = searchParams.get('page') ? parseInt(searchParams.get('page')!) : undefined;
      const pageSize = searchParams.get('pageSize') ? parseInt(searchParams.get('pageSize')!) : undefined;

      // Generate report data
      const reportData = await generateReport({
        reportId: report.id,
        filters,
        sortBy,
        sortOrder,
        page,
        pageSize,
        format: format as 'json' | 'html' | 'csv',
      });

      // Return based on format
      if (format === 'html') {
        const html = generateHTMLReport(
          report.name,
          (report.columns as unknown) as ReportColumn[],
          reportData
        );
        return new NextResponse(html, {
          headers: { 'Content-Type': 'text/html' },
        });
      }

      if (format === 'csv') {
        const csv = generateCSV((report.columns as unknown) as ReportColumn[], reportData);
        return new NextResponse(csv, {
          headers: {
            'Content-Type': 'text/csv',
            'Content-Disposition': `attachment; filename="${report.key}_${new Date().toISOString().split('T')[0]}.csv"`,
          },
        });
      }

      return NextResponse.json({
        report: {
          id: report.id,
          key: report.key,
          name: report.name,
          columns: report.columns,
          chartConfig: report.chartConfig,
        },
        data: reportData,
      });
    }

    return NextResponse.json(
      { error: 'Invalid action' },
      { status: 400 }
    );
  } catch (error) {
    console.error('Error with report:', error);
    return NextResponse.json(
      { error: 'Failed to process report request' },
      { status: 500 }
    );
  }
}

// PATCH - Update report definition (only for non-system reports)
export async function PATCH(request: NextRequest, { params }: RouteParams) {
  try {
    const { reportId } = await params;
    const body = await request.json();

    const report = await prisma.reportDefinition.findUnique({
      where: { id: reportId },
    });

    if (!report) {
      return NextResponse.json(
        { error: 'Report not found' },
        { status: 404 }
      );
    }

    // Only allow updating certain fields for system reports
    const updateData: Record<string, unknown> = {};

    if (report.isSystem) {
      // System reports: only allow enabling/disabling
      if (body.isActive !== undefined) updateData.isActive = body.isActive;
    } else {
      // Custom reports: allow full updates
      if (body.name) updateData.name = body.name;
      if (body.description !== undefined) updateData.description = body.description;
      if (body.queryConfig) updateData.queryConfig = body.queryConfig;
      if (body.columns) updateData.columns = body.columns;
      if (body.chartConfig !== undefined) updateData.chartConfig = body.chartConfig;
      if (body.defaultFilters) updateData.defaultFilters = body.defaultFilters;
      if (body.availableFilters) updateData.availableFilters = body.availableFilters;
      if (body.isActive !== undefined) updateData.isActive = body.isActive;
    }

    const updated = await prisma.reportDefinition.update({
      where: { id: reportId },
      data: updateData,
    });

    return NextResponse.json({ report: updated });
  } catch (error) {
    console.error('Error updating report:', error);
    return NextResponse.json(
      { error: 'Failed to update report' },
      { status: 500 }
    );
  }
}
