import { NextResponse } from 'next/server';
import { withErrorHandler } from '@server/middleware/withErrorHandler';
import { withAuth, requireSection, AuthedRequest } from '@server/middleware/withAuth';
import { ForbiddenError, ValidationError } from '@server/errors';
import { listCards, issueCard } from '@server/services/gift-cards.service';
import { resolveWritableBranchId } from '@server/utils/branch-access';
import { requirePlanFeature } from '@server/utils/features';

export const GET = withErrorHandler(
  withAuth(async (req: AuthedRequest) => {
    await requireSection(req, 'gift_cards');
    await requirePlanFeature(req.session.restaurantId!, 'gift_cards');
    const url = new URL(req.url);
    const p = url.searchParams;
    const queryBranch = p.get('branch_id') ?? undefined;
    const sessionBranch = req.session.pinnedBranchId ?? req.session.branchId ?? undefined;
    const branchId = req.session.pinnedBranchId
      ? req.session.pinnedBranchId
      : (queryBranch ?? sessionBranch);
    const result = await listCards(req.session.restaurantId!, {
      status: p.get('status') ?? undefined,
      search: p.get('search') ?? undefined,
      branchId: branchId ?? undefined,
      dateFrom: p.get('date_from') ?? undefined,
      dateTo: p.get('date_to') ?? undefined,
      page: parseInt(p.get('page') ?? '1', 10),
      limit: parseInt(p.get('limit') ?? '20', 10),
    });
    return NextResponse.json(result);
  })
);

export const POST = withErrorHandler(
  withAuth(async (req: AuthedRequest) => {
    await requirePlanFeature(req.session.restaurantId!, 'gift_cards');
    await requireSection(req, 'gift_cards', 'create');
    if (!['owner', 'admin', 'manager'].includes(req.session.role || '')) {
      throw new ForbiddenError('You do not have permission to issue gift cards');
    }
    const body = await req.json().catch(() => null);
    if (!body) throw new ValidationError('Request body is required');
    const requestedBranch = body.branch_id ?? req.session.branchId ?? null;
    const branchId = resolveWritableBranchId(req.session, requestedBranch);
    const result = await issueCard({
      restaurantId: req.session.restaurantId!,
      amount: Number(body.amount),
      recipientName: String(body.recipient_name ?? ''),
      recipientEmail: body.recipient_email ?? null,
      senderName: body.sender_name ?? null,
      senderEmail: body.sender_email ?? null,
      personalMessage: body.personal_message ?? null,
      expiresAt: body.expires_at ?? null,
      branchId,
      byUserId: req.session.userId ?? null,
      sendEmail: body.send_email !== false,
    });
    return NextResponse.json({ card: result }, { status: 201 });
  })
);
