<?php
global $db;
require_post();

$houseId = (int)($_POST['house_bl_id'] ?? 0);
$selected = $_POST['charge_type_id'] ?? []; // array of ids from checkboxes

if ($houseId <= 0) json_out(['ok'=>false,'msg'=>'Missing house_bl_id'], 400);

// Normalize selected ids
if (!is_array($selected)) $selected = [$selected];
$selectedIds = array_values(array_unique(array_filter(array_map('intval', $selected), fn($v)=>$v>0)));

if (!$selectedIds) {
  json_out(['ok'=>false,'msg'=>'Select at least one charge item to generate invoice.'], 422);
}

// Prevent duplicates
$existing = $db->prepare("SELECT id FROM invoices WHERE house_bl_id=? ORDER BY id DESC LIMIT 1");
$existing->execute([$houseId]);
$ex = $existing->fetch();
if ($ex) {
  $invoiceId = (int)$ex['id'];
  json_out([
    'ok'=>true,
    'invoice_id'=>$invoiceId,
    'url'=>to('/invoice.php?id=' . $invoiceId),
    'redirect'=>to('/invoice/view?id=' . $invoiceId),
    'existing'=>true
  ]);
}

// Load HBL
$h = $db->prepare("
  SELECT h.*, c1.name AS consignee_name, c2.name AS billing_name
  FROM house_bls h
  JOIN customers c1 ON c1.id=h.consignee_customer_id
  JOIN customers c2 ON c2.id=h.billing_party_customer_id
  WHERE h.id=?
");
$h->execute([$houseId]);
$hbl = $h->fetch();
if (!$hbl) json_out(['ok'=>false,'msg'=>'HBL not found'], 404);

// Fetch selected charges only
$in = implode(',', array_fill(0, count($selectedIds), '?'));
$chargesStmt = $db->prepare("
  SELECT id, name, basis, default_rate
  FROM charge_types
  WHERE id IN ($in)
  ORDER BY id ASC
");
$chargesStmt->execute($selectedIds);
$charges = $chargesStmt->fetchAll();
if (!$charges) json_out(['ok'=>false,'msg'=>'No valid charges selected'], 422);

$seq = next_number($db, 'invoice');
$invNo = 'INV-' . date('Y') . '-' . $seq;

$createdBy = (int)($_SESSION['uid'] ?? 0);
if ($createdBy <= 0) $createdBy = (int)($_SESSION['user_id'] ?? 1);

$db->beginTransaction();

try {
  $stmt = $db->prepare("
    INSERT INTO invoices(invoice_no, house_bl_id, consignee_customer_id, billing_party_customer_id, currency, status, issue_date, created_by)
    VALUES(?,?,?,?, 'USD', 'ISSUED', CURDATE(), ?)
  ");
  $stmt->execute([
    $invNo,
    $houseId,
    (int)$hbl['consignee_customer_id'],
    (int)$hbl['billing_party_customer_id'],
    $createdBy
  ]);

  $invoiceId = (int)$db->lastInsertId();

  $subtotal = 0.0; // base amount before VAT
  $vatTotal = 0.0; // VAT only on FLAT items at 16%

  foreach ($charges as $ch) {
    $basis = strtoupper(trim((string)($ch['basis'] ?? ''))); // FLAT or PER_UNIT_WM

    $qty = 1.0;
    if ($basis === 'PER_UNIT_WM') {
      $qty = (float)($hbl['chargeable_units'] ?? 0);
    }

    $unit = (float)($ch['default_rate'] ?? 0);
    $amount = round($qty * $unit, 2); // stored line amount remains base amount
    $subtotal += $amount;

    if ($basis === 'FLAT') {
      $vatTotal += round($amount * 0.16, 2);
    }

    $ins = $db->prepare("
      INSERT INTO invoice_items(invoice_id, charge_type_id, description, basis, qty, unit_price, amount)
      VALUES(?,?,?,?,?,?,?)
    ");
    $ins->execute([
      $invoiceId,
      (int)$ch['id'],
      (string)$ch['name'],
      $basis,
      $qty,
      $unit,
      $amount
    ]);
  }

  $subtotal = round($subtotal, 2);
  $vatTotal = round($vatTotal, 2);
  $total = round($subtotal + $vatTotal, 2);

  $upd = $db->prepare("UPDATE invoices SET subtotal=?, total=? WHERE id=?");
  $upd->execute([$subtotal, $total, $invoiceId]);

  $hblUpd = $db->prepare("
    UPDATE house_bls
    SET status='AWAITING_PAYMENT', updated_at=NOW()
    WHERE id=?
  ");
  $hblUpd->execute([$houseId]);

  $db->prepare("
    INSERT INTO invoice_events (invoice_id, event_type, user_id, ip_address, user_agent, meta)
    VALUES (?, 'CREATED', ?, ?, ?, ?)
  ")->execute([
    $invoiceId,
    ($_SESSION['uid'] ?? $_SESSION['user_id'] ?? null),
    ($_SERVER['REMOTE_ADDR'] ?? null),
    ($_SERVER['HTTP_USER_AGENT'] ?? null),
    json_encode([
      'selected_charge_type_ids' => $selectedIds,
      'vat_rate_flat_only' => 16,
      'vat_total' => $vatTotal
    ])
  ]);

  $db->commit();

  json_out([
    'ok'=>true,
    'invoice_id'=>$invoiceId,
    'url'=>to('/invoice.php?id=' . $invoiceId),
    'redirect'=>to('/invoice/view?id=' . $invoiceId),
  ]);

} catch (Throwable $e) {
  $db->rollBack();
  json_out(['ok'=>false,'msg'=>'Invoice creation failed'], 500);
}