<?php
declare(strict_types=1);
/**
 * modules/invoices/add.php
 *
 * Create a manual invoice (not from a booking).
 * Parts:
 *  1) Bootstrap & guards
 *  2) Helpers (generate invoice no)
 *  3) Handle POST (validate, compute, insert)
 *  4) Defaults for initial form
 *  5) Render form + JS (dynamic lines, totals)
 */

////////////////////////////////////////////////////////////////
// 1) Bootstrap & guards
////////////////////////////////////////////////////////////////
require_once dirname(__DIR__, 2) . '/config/functions.php';
require_role(['Admin','Ops']);

$user = current_user();
$cid  = (int)($user['company_id'] ?? 0);
if ($cid <= 0) redirect(url_public('login.php'));

$errors = [];
$notice = null;

////////////////////////////////////////////////////////////////
// 2) Helpers
////////////////////////////////////////////////////////////////
/**
 * Generate invoice number like INV-YYYYMMDD-### (per day per company)
 * Ensures the ### increments for the day.
 */
function generate_invoice_no(int $companyId): string {
  $today   = date('Y-m-d');
  $prefixD = date('Ymd');
  $prefix  = "INV-{$prefixD}-";
  $stmt = db()->prepare("
    SELECT invoice_no
      FROM invoices
     WHERE company_id = :cid
       AND invoice_date = :d
       AND invoice_no LIKE :pref
  ");
  $stmt->execute([':cid'=>$companyId, ':d'=>$today, ':pref'=>$prefix.'%']);
  $max = 0;
  while ($row = $stmt->fetch()) {
    $no = (string)$row['invoice_no'];
    $parts = explode('-', $no);
    $last  = end($parts);
    if (ctype_digit($last)) {
      $n = (int)$last;
      if ($n > $max) $max = $n;
    }
  }
  $next = $max + 1;
  return $prefix . str_pad((string)$next, 3, '0', STR_PAD_LEFT);
}

////////////////////////////////////////////////////////////////
// 3) Handle POST (validate, compute, insert)
////////////////////////////////////////////////////////////////
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  try {
    csrf_verify((string)($_POST['csrf'] ?? ''));

    // --- Collect inputs
    $invoice_no   = trim((string)($_POST['invoice_no'] ?? ''));
    $invoice_date = trim((string)($_POST['invoice_date'] ?? ''));
    $due_date     = trim((string)($_POST['due_date'] ?? ''));

    $bill_name    = trim((string)($_POST['bill_to_name'] ?? ''));
    $bill_email   = trim((string)($_POST['bill_to_email'] ?? ''));
    $bill_addr    = trim((string)($_POST['bill_to_address'] ?? ''));

    $discount     = (float)($_POST['discount_amount'] ?? 0);
    $vat_rate     = (float)($_POST['vat_rate'] ?? 0);
    $notes        = trim((string)($_POST['notes'] ?? ''));

    // Lines
    $desc = $_POST['desc'] ?? [];
    $qty  = $_POST['qty']  ?? [];
    $unit = $_POST['unit'] ?? [];

    // --- Basic validation
    if ($invoice_no === '') $invoice_no = generate_invoice_no($cid);
    if ($invoice_date === '') $invoice_date = date('Y-m-d');
    if ($due_date === '')     $due_date     = date('Y-m-d', strtotime($invoice_date.' +14 days'));
    if ($bill_name === '')    $errors[] = 'Invoice To (name) is required.';

    // Prepare lines, compute totals
    $lines = [];
    $sub   = 0.0;

    $maxLen = max(count($desc), count($qty), count($unit));
    for ($i=0; $i<$maxLen; $i++) {
      $d = isset($desc[$i]) ? trim((string)$desc[$i]) : '';
      $q = isset($qty[$i])  ? (int)$qty[$i] : 0;
      $u = isset($unit[$i]) ? (float)$unit[$i] : 0.00;

      if ($d === '' && $q === 0 && $u == 0.00) continue; // skip empty row
      if ($d === '') { $errors[] = 'Each line must have a description.'; break; }
      if ($q <= 0)   { $errors[] = 'Quantity must be greater than 0.';  break; }

      $lt = $q * $u;
      $sub += $lt;
      $lines[] = ['description'=>$d, 'quantity'=>$q, 'unit_price'=>$u, 'line_total'=>$lt];
    }

    if (!$lines) $errors[] = 'Add at least one line item.';

    // Totals
    $discount = max(0.0, $discount);
    $tax_base = max(0.0, $sub - $discount);
    $vat_rate = max(0.0, $vat_rate);
    $vat_amt  = round($tax_base * ($vat_rate/100), 2);
    $grand    = round($tax_base + $vat_amt, 2);

    // Check duplicate invoice_no
    $dup = db()->prepare("SELECT id FROM invoices WHERE company_id=:cid AND invoice_no=:no LIMIT 1");
    $dup->execute([':cid'=>$cid, ':no'=>$invoice_no]);
    if ($dup->fetch()) $errors[] = 'Invoice number already exists.';

    if (!$errors) {
      db()->beginTransaction();

      $ins = db()->prepare("
        INSERT INTO invoices (
          company_id, invoice_no, booking_id,
          bill_to_name, bill_to_email, bill_to_address,
          invoice_date, due_date,
          subtotal_amount, discount_amount, vat_rate, vat_amount, total_amount,
          paid_total, status, notes, created_at, updated_at
        ) VALUES (
          :cid, :no, NULL,
          :bn, :be, :ba,
          :idate, :ddate,
          :sub, :disc, :vr, :va, :grand,
          0.00, 'draft', :notes, NOW(), NOW()
        )
      ");
      $ins->execute([
        ':cid'   => $cid,
        ':no'    => $invoice_no,
        ':bn'    => $bill_name !== '' ? $bill_name : null,
        ':be'    => $bill_email !== '' ? $bill_email : null,
        ':ba'    => $bill_addr  !== '' ? $bill_addr  : null,
        ':idate' => $invoice_date,
        ':ddate' => $due_date,
        ':sub'   => $sub,
        ':disc'  => $discount,
        ':vr'    => $vat_rate,
        ':va'    => $vat_amt,
        ':grand' => $grand,
        ':notes' => $notes !== '' ? $notes : null,
      ]);
      $iid = (int)db()->lastInsertId();

      $insL = db()->prepare("
        INSERT INTO invoice_lines (invoice_id, description, quantity, unit_price, line_total)
        VALUES (:iid, :d, :q, :u, :lt)
      ");
      foreach ($lines as $ln) {
        $insL->execute([
          ':iid' => $iid,
          ':d'   => $ln['description'],
          ':q'   => $ln['quantity'],
          ':u'   => $ln['unit_price'],
          ':lt'  => $ln['line_total'],
        ]);
      }

      db()->commit();
      audit_log('invoice.create', 'invoice', $iid, ['invoice_no'=>$invoice_no, 'total'=>$grand]);

      // Go to view
      redirect(url_modules('invoices/view.php').'?id='.$iid);
    }
  } catch (Throwable $e) {
    if (db()->inTransaction()) db()->rollBack();
    $errors[] = (defined('APP_ENV') && APP_ENV === 'dev') ? $e->getMessage() : 'Unable to create invoice.';
  }
}

////////////////////////////////////////////////////////////////
// 4) Defaults for initial form (suggestions)
////////////////////////////////////////////////////////////////
$def_invoice_no   = generate_invoice_no($cid);
$def_invoice_date = date('Y-m-d');
$def_due_date     = date('Y-m-d', strtotime('+14 days'));

include dirname(__DIR__, 2) . '/includes/header.php';
?>
<div class="d-flex justify-content-between align-items-center mb-3">
  <h1 class="h4 mb-0">New Invoice</h1>
  <div class="d-flex gap-2">
    <a href="<?= e(url_modules('invoices/generate_from_booking.php')) ?>" class="btn btn-outline-secondary">From Booking</a>
    <a href="<?= e(url_modules('invoices/list.php')) ?>" class="btn btn-outline-secondary">Back</a>
  </div>
</div>

<?php if ($errors): ?>
  <div class="alert alert-danger"><ul class="mb-0"><?php foreach ($errors as $er) echo '<li>'.e($er).'</li>'; ?></ul></div>
<?php endif; ?>

<form method="post" id="invoiceForm" autocomplete="off">
  <input type="hidden" name="csrf" value="<?= e(csrf_token()) ?>">

  <!-- Sticky action bar -->
  <div class="position-sticky top-0 z-3 pb-2" style="background:#f8fafc;">
    <div class="d-flex justify-content-between align-items-center mb-2 pt-2">
      <div class="small text-muted">Manual invoice (custom line items)</div>
      <div class="d-flex gap-2">
        <button type="submit" class="btn btn-dark">Save Invoice</button>
      </div>
    </div>
  </div>

  <div class="row g-3">
    <!-- Left Column -->
    <div class="col-12 col-lg-7">
      <div class="card shadow-sm">
        <div class="card-body">
          <h2 class="h6 text-uppercase text-muted mb-3">Bill To</h2>
          <div class="row g-3">
            <div class="col-md-6">
              <label class="form-label">Invoice To (Name) <span class="text-danger">*</span></label>
              <input class="form-control" name="bill_to_name" required
                     value="<?= e($_POST['bill_to_name'] ?? '') ?>">
            </div>
            <div class="col-md-6">
              <label class="form-label">Email</label>
              <input type="email" class="form-control" name="bill_to_email"
                     value="<?= e($_POST['bill_to_email'] ?? '') ?>">
            </div>
            <div class="col-12">
              <label class="form-label">Address</label>
              <textarea class="form-control" name="bill_to_address" rows="2"><?= e($_POST['bill_to_address'] ?? '') ?></textarea>
            </div>
          </div>

          <hr class="my-3">

          <h2 class="h6 text-uppercase text-muted mb-2">Line Items</h2>
          <div class="table-responsive">
            <table class="table align-middle" id="linesTable">
              <thead class="table-light">
                <tr>
                  <th style="width:48px;">#</th>
                  <th>Description</th>
                  <th style="width:100px;" class="text-end">Qty</th>
                  <th style="width:140px;" class="text-end">Unit £</th>
                  <th style="width:140px;" class="text-end">Line Total £</th>
                  <th style="width:60px;"></th>
                </tr>
              </thead>
              <tbody>
                <!-- Rows injected by JS -->
              </tbody>
            </table>
          </div>
          <button type="button" class="btn btn-sm btn-outline-primary" id="btnAddLine">Add Line</button>

          <hr class="my-3">

          <h2 class="h6 text-uppercase text-muted mb-2">Notes</h2>
          <textarea class="form-control" name="notes" rows="2"
            placeholder="Internal notes (optional)"><?= e($_POST['notes'] ?? '') ?></textarea>
        </div>
      </div>
    </div>

    <!-- Right Column -->
    <div class="col-12 col-lg-5">
      <div class="card shadow-sm">
        <div class="card-body">
          <h2 class="h6 text-uppercase text-muted mb-3">Invoice</h2>
          <div class="row g-3">
            <div class="col-md-6">
              <label class="form-label">Invoice #</label>
              <input class="form-control" name="invoice_no"
                     value="<?= e($_POST['invoice_no'] ?? $def_invoice_no) ?>">
              <div class="form-text">Auto-suggested; you can edit.</div>
            </div>
            <div class="col-md-3">
              <label class="form-label">Date</label>
              <input type="date" class="form-control" name="invoice_date"
                     value="<?= e($_POST['invoice_date'] ?? $def_invoice_date) ?>">
            </div>
            <div class="col-md-3">
              <label class="form-label">Due</label>
              <input type="date" class="form-control" name="due_date"
                     value="<?= e($_POST['due_date'] ?? $def_due_date) ?>">
            </div>

            <div class="col-md-5">
              <label class="form-label">Discount (£)</label>
              <input type="number" step="0.01" min="0" class="form-control js-calc" name="discount_amount"
                     value="<?= e($_POST['discount_amount'] ?? '0.00') ?>">
            </div>
            <div class="col-md-4">
              <label class="form-label">VAT %</label>
              <input type="number" step="0.01" min="0" class="form-control js-calc" name="vat_rate"
                     value="<?= e($_POST['vat_rate'] ?? '0.00') ?>">
            </div>
          </div>

          <div class="row g-2 mt-3">
            <div class="col-12">
              <div class="p-2 border rounded bg-light">
                <div class="d-flex justify-content-between small">
                  <div class="text-muted">Subtotal</div>
                  <div id="sumSub">0.00</div>
                </div>
                <div class="d-flex justify-content-between small">
                  <div class="text-muted">Discount</div>
                  <div id="sumDisc">0.00</div>
                </div>
                <div class="d-flex justify-content-between small">
                  <div class="text-muted">VAT</div>
                  <div id="sumVat">0.00</div>
                </div>
                <div class="d-flex justify-content-between fw-bold">
                  <div>Total Due</div>
                  <div id="sumGrand">0.00</div>
                </div>
              </div>
            </div>
          </div>

          <div class="alert alert-info mt-3 mb-0 small">
            This invoice will be created as <strong>Draft</strong>. You can email the PDF from the invoice page.
          </div>
        </div>
      </div>
    </div>
  </div>

  <div class="mt-3 d-flex gap-2">
    <button type="submit" class="btn btn-dark">Save Invoice</button>
    <a class="btn btn-outline-secondary" href="<?= e(url_modules('invoices/list.php')) ?>">Cancel</a>
  </div>
</form>

<?php include dirname(__DIR__, 2) . '/includes/footer.php'; ?>

<script>
(function(){
  const tbody = document.querySelector('#linesTable tbody');
  const btnAdd = document.getElementById('btnAddLine');

  function addRow(d='', q='', u='') {
    const tr = document.createElement('tr');
    tr.innerHTML = `
      <td class="align-middle row-index"></td>
      <td><textarea class="form-control form-control-sm desc" name="desc[]" rows="1" placeholder="Description..."></textarea></td>
      <td><input type="number" step="1" min="1" class="form-control form-control-sm text-end qty"  name="qty[]"  value="1"></td>
      <td><input type="number" step="0.01" min="0" class="form-control form-control-sm text-end unit" name="unit[]" value="0.00"></td>
      <td class="text-end align-middle lt">0.00</td>
      <td><button type="button" class="btn btn-sm btn-outline-danger btn-del">Del</button></td>
    `;
    tbody.appendChild(tr);
    if (d) tr.querySelector('.desc').value = d;
    if (q) tr.querySelector('.qty').value  = q;
    if (u) tr.querySelector('.unit').value = u;
    renumber();
    recalc();
  }
  function renumber() {
    [...tbody.rows].forEach((tr, i) => {
      const idx = tr.querySelector('.row-index');
      if (idx) idx.textContent = String(i+1);
    });
  }
  function num(v){ const n = parseFloat(v); return isNaN(n) ? 0 : n; }
  function recalc() {
    let sub = 0;
    [...tbody.rows].forEach(tr => {
      const q = num(tr.querySelector('.qty').value);
      const u = num(tr.querySelector('.unit').value);
      const lt = q * u;
      sub += lt;
      tr.querySelector('.lt').textContent = lt.toFixed(2);
    });
    const disc = num(document.querySelector('input[name="discount_amount"]').value);
    const vr   = num(document.querySelector('input[name="vat_rate"]').value);
    const base = Math.max(0, sub - disc);
    const vat  = base * (vr/100);
    const grand= base + vat;

    document.getElementById('sumSub').textContent   = sub.toFixed(2);
    document.getElementById('sumDisc').textContent  = disc.toFixed(2);
    document.getElementById('sumVat').textContent   = vat.toFixed(2);
    document.getElementById('sumGrand').textContent = grand.toFixed(2);
  }

  btnAdd.addEventListener('click', () => addRow());

  tbody.addEventListener('input', e => {
    if (e.target.matches('.qty, .unit, .desc')) recalc();
  });
  tbody.addEventListener('click', e => {
    const b = e.target.closest('.btn-del');
    if (!b) return;
    b.closest('tr')?.remove();
    renumber();
    recalc();
  });

  document.querySelectorAll('.js-calc').forEach(el => el.addEventListener('input', recalc));

  // Start with one empty row
  addRow();
})();
</script>
