/**
 * Admin Invoice Management Routes
 *
 * Endpoints for viewing invoice records (tax/legal compliance)
 */

import { Router, Request, Response } from 'express';
import { PrismaClient } from '@prisma/client';
import { authenticateAdmin } from '../../middleware/auth';
import { logger } from '../../utils/logger';
import { PaginatedResponse } from '../../types';

const router = Router();
const prisma = new PrismaClient();

/**
 * GET /v1/admin/invoices
 * List all invoices with pagination and filtering
 *
 * Query params:
 *   page       - page number (default 1)
 *   limit      - page size (default 20, max 100)
 *   userId     - filter by user UUID
 *   status     - filter by invoice status (draft|issued|paid|void)
 *   from       - filter issued_at >= (ISO date string)
 *   to         - filter issued_at <= (ISO date string)
 *   sortOrder  - asc|desc (default desc)
 */
router.get('/', authenticateAdmin, async (req: Request, res: Response) => {
  try {
    const {
      page = '1',
      limit = '20',
      userId,
      status,
      from,
      to,
      sortOrder = 'desc',
    } = req.query;

    const pageNum = Math.max(1, parseInt(page as string));
    const limitNum = Math.min(100, Math.max(1, parseInt(limit as string)));
    const skip = (pageNum - 1) * limitNum;

    const where: any = {};

    if (userId) {
      where.user_id = userId as string;
    }

    if (status) {
      where.status = status as string;
    }

    if (from || to) {
      where.issued_at = {};
      if (from) {
        where.issued_at.gte = new Date(from as string);
      }
      if (to) {
        where.issued_at.lte = new Date(to as string);
      }
    }

    const orderBy = { issued_at: sortOrder === 'asc' ? ('asc' as const) : ('desc' as const) };

    const [invoices, total] = await Promise.all([
      prisma.invoice.findMany({
        where,
        skip,
        take: limitNum,
        orderBy,
        include: {
          user: {
            select: {
              id: true,
              email: true,
              status: true,
            },
          },
          payment: {
            select: {
              id: true,
              paypal_payment_id: true,
              amount: true,
              status: true,
              type: true,
            },
          },
          subscription: {
            select: {
              id: true,
              plan_tier: true,
              billing_cycle: true,
              status: true,
            },
          },
        },
      }),
      prisma.invoice.count({ where }),
    ]);

    const totalPages = Math.ceil(total / limitNum);

    const response: PaginatedResponse<any> = {
      data: invoices.map((inv) => ({
        id: inv.id,
        invoiceNumber: inv.invoice_number,
        userId: inv.user_id,
        user: {
          id: inv.user.id,
          email: inv.user.email,
          status: inv.user.status,
        },
        payment: inv.payment
          ? {
              id: inv.payment.id,
              paypalPaymentId: inv.payment.paypal_payment_id,
              amount: inv.payment.amount.toString(),
              status: inv.payment.status,
              type: inv.payment.type,
            }
          : null,
        subscription: inv.subscription
          ? {
              id: inv.subscription.id,
              planTier: inv.subscription.plan_tier,
              billingCycle: inv.subscription.billing_cycle,
              status: inv.subscription.status,
            }
          : null,
        amount: inv.amount.toString(),
        currency: inv.currency,
        status: inv.status,
        issuedAt: inv.issued_at.toISOString(),
        dueAt: inv.due_at?.toISOString() ?? null,
        paidAt: inv.paid_at?.toISOString() ?? null,
        pdfUrl: inv.pdf_url ?? null,
      })),
      pagination: {
        page: pageNum,
        limit: limitNum,
        total,
        totalPages,
        hasNext: pageNum < totalPages,
        hasPrev: pageNum > 1,
      },
    };

    res.json(response);
  } catch (error) {
    logger.error('Error fetching invoices list', { error, adminId: req.admin?.id });
    res.status(500).json({
      error: true,
      code: 'INTERNAL_ERROR',
      message: 'Failed to fetch invoices',
      timestamp: new Date().toISOString(),
    });
  }
});

/**
 * GET /v1/admin/invoices/:id
 * Get detailed information about a specific invoice
 */
router.get('/:id', authenticateAdmin, async (req: Request, res: Response) => {
  try {
    const { id } = req.params;

    const invoice = await prisma.invoice.findUnique({
      where: { id },
      include: {
        user: {
          select: {
            id: true,
            email: true,
            status: true,
            subscriptions: {
              select: {
                plan_tier: true,
                status: true,
                billing_cycle: true,
              },
            },
          },
        },
        payment: {
          select: {
            id: true,
            paypal_payment_id: true,
            amount: true,
            currency: true,
            status: true,
            type: true,
            created_at: true,
          },
        },
        subscription: {
          select: {
            id: true,
            plan_tier: true,
            billing_cycle: true,
            status: true,
            current_period_start: true,
            current_period_end: true,
          },
        },
      },
    });

    if (!invoice) {
      res.status(404).json({
        error: true,
        code: 'INVOICE_NOT_FOUND',
        message: 'Invoice not found',
        timestamp: new Date().toISOString(),
      });
      return;
    }

    res.json({
      id: invoice.id,
      invoiceNumber: invoice.invoice_number,
      userId: invoice.user_id,
      user: {
        id: invoice.user.id,
        email: invoice.user.email,
        status: invoice.user.status,
        subscription: invoice.user.subscriptions[0]
          ? {
              plan: invoice.user.subscriptions[0].plan_tier,
              status: invoice.user.subscriptions[0].status,
              billingCycle: invoice.user.subscriptions[0].billing_cycle,
            }
          : null,
      },
      payment: invoice.payment
        ? {
            id: invoice.payment.id,
            paypalPaymentId: invoice.payment.paypal_payment_id,
            amount: invoice.payment.amount.toString(),
            currency: invoice.payment.currency,
            status: invoice.payment.status,
            type: invoice.payment.type,
            createdAt: invoice.payment.created_at.toISOString(),
          }
        : null,
      subscription: invoice.subscription
        ? {
            id: invoice.subscription.id,
            planTier: invoice.subscription.plan_tier,
            billingCycle: invoice.subscription.billing_cycle,
            status: invoice.subscription.status,
            currentPeriodStart: invoice.subscription.current_period_start.toISOString(),
            currentPeriodEnd: invoice.subscription.current_period_end.toISOString(),
          }
        : null,
      amount: invoice.amount.toString(),
      currency: invoice.currency,
      status: invoice.status,
      lineItems: invoice.line_items,
      billingAddress: invoice.billing_address,
      notes: invoice.notes ?? null,
      issuedAt: invoice.issued_at.toISOString(),
      dueAt: invoice.due_at?.toISOString() ?? null,
      paidAt: invoice.paid_at?.toISOString() ?? null,
      pdfUrl: invoice.pdf_url ?? null,
    });
  } catch (error) {
    logger.error('Error fetching invoice details', {
      error,
      invoiceId: req.params.id,
      adminId: req.admin?.id,
    });
    res.status(500).json({
      error: true,
      code: 'INTERNAL_ERROR',
      message: 'Failed to fetch invoice details',
      timestamp: new Date().toISOString(),
    });
  }
});

export default router;
