'use server';

import { redirect } from 'next/navigation';
import { prisma } from '@/lib/prisma';
import { applyStockMovement } from '@/lib/stock';

export type ManualSaleItemInput = {
  productId: string | null; // null = free-text one-off
  description: string;
  color: string | null;
  size: string | null;
  quantity: number;
  unitPrice: number; // pence
};

export async function createManualSale(formData: FormData) {
  const soldAtInput = String(formData.get('soldAt') ?? '').trim();
  const buyerName = String(formData.get('buyerName') ?? '').trim();
  const buyerEmail = String(formData.get('buyerEmail') ?? '').trim().toLowerCase();
  const paymentMethod = String(formData.get('paymentMethod') ?? 'CASH');
  const notes = String(formData.get('notes') ?? '').trim();
  const itemsJson = String(formData.get('items') ?? '[]');

  if (!['CASH', 'BANK_TRANSFER'].includes(paymentMethod)) {
    throw new Error('Unknown payment method.');
  }

  let items: ManualSaleItemInput[];
  try {
    items = JSON.parse(itemsJson);
  } catch {
    throw new Error('Could not read the sale items.');
  }
  items = items.filter((i) => i.description.trim() && i.quantity > 0);
  if (items.length === 0) {
    throw new Error('A sale needs at least one item.');
  }
  for (const item of items) {
    if (!Number.isInteger(item.quantity) || item.quantity < 1 || item.quantity > 10000) {
      throw new Error('Quantities must be whole numbers.');
    }
    if (!Number.isInteger(item.unitPrice) || item.unitPrice < 0) {
      throw new Error('Prices cannot be negative.');
    }
  }

  // Total always recomputed here — never trusted from the client.
  const total = items.reduce((sum, i) => sum + i.quantity * i.unitPrice, 0);

  // Auto-link to an existing customer account when the email matches, so this
  // sale shows up in their combined purchase history later.
  const customer = buyerEmail ? await prisma.customer.findUnique({ where: { email: buyerEmail } }) : null;

  await prisma.manualSale.create({
    data: {
      soldAt: soldAtInput ? new Date(soldAtInput) : new Date(),
      buyerName: buyerName || null,
      buyerEmail: buyerEmail || null,
      customerId: customer?.id ?? null,
      paymentMethod,
      total,
      notes: notes || null,
      items: {
        create: items.map((i) => ({
          productId: i.productId,
          description: i.description.trim(),
          color: i.color,
          size: i.size,
          quantity: i.quantity,
          unitPrice: i.unitPrice,
        })),
      },
    },
  });

  // Product lines reduce stock; free-text lines carry none.
  await applyStockMovement(items, -1);

  redirect('/admin/accounts');
}

export async function deleteManualSale(formData: FormData) {
  const id = String(formData.get('id') ?? '');
  if (!id) return;
  const sale = await prisma.manualSale.findUnique({ where: { id }, include: { items: true } });
  if (!sale) return;
  await prisma.manualSale.delete({ where: { id } });
  // Deleting a sale puts its stock back — the sale never happened.
  await applyStockMovement(sale.items, 1);
  redirect('/admin/accounts');
}
