<?php
declare(strict_types=1);
/**
 * modules/bookings/add.php
 *
 * Create a booking (with or without assigning vehicles/drivers).
 * - Driver-first: selecting a driver with an own vehicle auto-applies their reg/type
 *   into the booking row (vehicle_id stays NULL). Can override with a pool vehicle.
 * - No requirement to add any assignment rows; you can assign later.
 * - Commission fixed amount field (for partners who take fixed £ per job).
 * - Flight number (optional).
 * - Corporate Client (optional): dropdown from corporates; stores corporates.id into bookings.corporate_id
 *
 * Requires helpers: db(), e(), csrf_token(), csrf_verify(), require_role(),
 * current_user(), generate_booking_ref(), audit_log(), url_modules()
 */

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'));

/* ---------- Reference data ---------- */
$pdo = db();

// Drivers (include own-vehicle info for auto UX)
$driversStmt = $pdo->prepare("
  SELECT id, name, phone,
         COALESCE(own_vehicle_reg_no,'') AS own_vehicle_reg_no,
         COALESCE(own_vehicle_type,'')   AS own_vehicle_type
  FROM drivers
  WHERE company_id = :cid AND is_active = 1
  ORDER BY name
");
$driversStmt->execute([':cid' => $cid]);
$drivers = $driversStmt->fetchAll();

// Vehicles (company pool)
$vehiclesStmt = $pdo->prepare("
  SELECT id, reg_no, type
  FROM vehicles
  WHERE company_id = :cid
  ORDER BY reg_no
");
$vehiclesStmt->execute([':cid' => $cid]);
$vehicles = $vehiclesStmt->fetchAll();

// Partners
$partnersStmt = $pdo->prepare("
  SELECT id, name
  FROM partners
  WHERE company_id = :cid
  ORDER BY name
");
$partnersStmt->execute([':cid' => $cid]);
$partners = $partnersStmt->fetchAll();

// Corporates (active only)
$corporatesStmt = $pdo->prepare("
  SELECT id, name
  FROM corporates
  WHERE company_id = :cid AND status = 'active'
  ORDER BY name
");
$corporatesStmt->execute([':cid' => $cid]);
$corporates = $corporatesStmt->fetchAll();

$errors = [];

// For the initial suggestion, prefer posted pickup_date (if the form just failed), else today.
$prefillPickupDate = $_POST['pickup_date'] ?? null;
$suggestedRef = generate_booking_ref($cid, $prefillPickupDate ?: null);

/* ---------- Handle submit ---------- */
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  try {
    csrf_verify($_POST['csrf'] ?? '');

    // Normalize inputs
    $type         = (string)($_POST['booking_type'] ?? 'Transfer');
    $hours        = ($_POST['hours'] ?? '') !== '' ? (string)$_POST['hours'] : null;

    $client_name  = trim((string)($_POST['client_name'] ?? ''));
    $client_phone = trim((string)($_POST['client_phone'] ?? ''));
    $client_email = trim((string)($_POST['client_email'] ?? ''));

    $flight       = trim((string)($_POST['flight_number'] ?? ''));

    $pickup_date  = (string)($_POST['pickup_date'] ?? '');
    $pickup_time  = (string)$_POST['pickup_time'] ?? '';
    $pickup_addr  = trim((string)($_POST['pickup_address'] ?? ''));
    $via          = trim((string)($_POST['via'] ?? ''));
    $drop_addr    = trim((string)($_POST['dropoff_address'] ?? ''));

    $pax          = (int)($_POST['pax_count'] ?? 0);
    $lug          = (int)($_POST['luggage_count'] ?? 0);

    $partner_id   = (int)($_POST['partner_id'] ?? 0);
    if ($partner_id === 0) $partner_id = null;

    // NEW: corporate_id (nullable)
    $corporate_id = (int)($_POST['corporate_id'] ?? 0);
    if ($corporate_id === 0) $corporate_id = null;

    $commission_fixed = (float)($_POST['partner_commission_amount'] ?? 0);
    $notes        = trim((string)($_POST['notes'] ?? ''));

    if ($pickup_date === '' || $pickup_time === '') {
      $errors[] = 'Pickup date and time are required.';
    }

    // Handle booking reference
    $refRaw  = trim((string)($_POST['booking_ref'] ?? ''));
    $autoRef = ($refRaw === ''); // if blank, we auto-generate

    // Row arrays (optional)
    $bv_vehicle_id      = $_POST['bv_vehicle_id']      ?? [];
    $bv_driver_id       = $_POST['bv_driver_id']       ?? [];
    $bv_client_price    = $_POST['bv_client_price']    ?? [];
    $bv_driver_price    = $_POST['bv_driver_price']    ?? [];
    $bv_vehicle_reg_no  = $_POST['bv_vehicle_reg_no']  ?? []; // hidden free-text (own vehicle)
    $bv_vehicle_type    = $_POST['bv_vehicle_type']    ?? []; // hidden free-text (own vehicle)

    // Quick vehicle index
    $vehIndex = [];
    foreach ($vehicles as $v) $vehIndex[(int)$v['id']] = $v;

    // Reference uniqueness utility
    $existsRefStmt = $pdo->prepare("SELECT id FROM bookings WHERE company_id=:cid AND booking_ref=:ref LIMIT 1");
    $ref = $refRaw;

    if (!$errors) {
      if ($autoRef) {
        // Generate based on pickup_date and loop until unique (cap to avoid infinite loop)
        $attempts = 0;
        do {
          $ref = generate_booking_ref($cid, $pickup_date ?: null);
          $existsRefStmt->execute([':cid' => $cid, ':ref' => $ref]);
          $exists = $existsRefStmt->fetch();
          $attempts++;
        } while ($exists && $attempts < 10);

        if ($exists) {
          $errors[] = 'Unable to generate a unique booking reference. Please try again.';
        }
      } else {
        // Manual ref typed — must be unique
        $existsRefStmt->execute([':cid' => $cid, ':ref' => $ref]);
        if ($existsRefStmt->fetch()) {
          $errors[] = 'Booking reference already exists.';
        }
      }
    }

    // If OK, insert booking & rows
    if (!$errors) {
      $pdo->beginTransaction();

      $ins = $pdo->prepare("
        INSERT INTO bookings (
          company_id, booking_ref, partner_id, corporate_id, booking_type, hours,
          client_name, client_phone, client_email, flight_number,
          pickup_date, pickup_time, pickup_address, via, dropoff_address,
          pax_count, luggage_count, notes, status,
          total_client_price, total_driver_price,
          client_parking_fee, client_waiting_fee, driver_parking_fee, driver_waiting_fee,
          partner_commission_amount,
          created_by, created_at
        )
        VALUES (
          :cid, :ref, :pid, :corp, :bt, :hrs,
          :cn, :cp, :ce, :fl,
          :pd, :pt, :pa, :via, :da,
          :pax, :lug, :notes, 'New',
          0, 0,
          0, 0, 0, 0,
          :pc,
          :uid, NOW()
        )
      ");
      $ins->execute([
        ':cid'  => $cid,
        ':ref'  => $ref,
        ':pid'  => $partner_id,
        ':corp' => $corporate_id,
        ':bt'   => $type,
        ':hrs'  => $hours,
        ':cn'   => $client_name !== '' ? $client_name : null,
        ':cp'   => $client_phone !== '' ? $client_phone : null,
        ':ce'   => $client_email !== '' ? $client_email : null,
        ':fl'   => $flight !== '' ? $flight : null,
        ':pd'   => $pickup_date,
        ':pt'   => $pickup_time,
        ':pa'   => $pickup_addr !== '' ? $pickup_addr : null,
        ':via'  => $via !== '' ? $via : null,
        ':da'   => $drop_addr !== '' ? $drop_addr : null,
        ':pax'  => $pax,
        ':lug'  => $lug,
        ':notes'=> $notes !== '' ? $notes : null,
        ':pc'   => $commission_fixed,
        ':uid'  => $user['id'] ?? null,
      ]);
      $bid = (int)$pdo->lastInsertId();

      // Insert booking_vehicles (if any) + compute totals
      $sum_client = 0.0;
      $sum_driver = 0.0;
      $seq = 1;

      $maxLen = max(
        count($bv_vehicle_id),
        count($bv_driver_id),
        count($bv_client_price),
        count($bv_driver_price),
        count($bv_vehicle_reg_no),
        count($bv_vehicle_type)
      );

      // Fallback to fetch a driver's own vehicle server-side
      $drvStmt = $pdo->prepare("
        SELECT COALESCE(own_vehicle_reg_no,'') AS reg_no,
               COALESCE(own_vehicle_type,'')   AS vtype
        FROM drivers
        WHERE id = :id AND company_id = :cid
        LIMIT 1
      ");

      $insBV = $pdo->prepare("
        INSERT INTO booking_vehicles
          (booking_id, vehicle_id, vehicle_type, vehicle_reg_no, driver_id, driver_price, client_price, sequence_order)
        VALUES
          (:bid, :vid, :vt, :vr, :did, :dp, :cp, :seq)
      ");

      for ($i = 0; $i < $maxLen; $i++) {
        $vehId   = isset($bv_vehicle_id[$i]) ? (int)$bv_vehicle_id[$i] : 0;
        $drvId   = isset($bv_driver_id[$i]) ? (int)$bv_driver_id[$i] : 0;
        $cp      = isset($bv_client_price[$i]) ? (float)$bv_client_price[$i] : 0.0;
        $dp      = isset($bv_driver_price[$i]) ? (float)$bv_driver_price[$i] : 0.0;
        $ownReg  = isset($bv_vehicle_reg_no[$i]) ? trim((string)$bv_vehicle_reg_no[$i]) : '';
        $ownType = isset($bv_vehicle_type[$i])   ? trim((string)$bv_vehicle_type[$i])   : '';

        // Skip empty rows
        if (!$vehId && !$drvId && $cp == 0.0 && $dp == 0.0 && $ownReg === '' && $ownType === '') {
          continue;
        }

        $vehIdOrNull   = null;
        $vehRegToSave  = null;
        $vehTypeToSave = null;

        if ($vehId) {
          // Company pool vehicle
          $vehIdOrNull = $vehId;
          if (isset($vehIndex[$vehId])) {
            $vehRegToSave  = (string)$vehIndex[$vehId]['reg_no'];
            $vehTypeToSave = (string)$vehIndex[$vehId]['type'];
          }
        } else {
          // Own vehicle (hidden fields or fallback)
          if ($ownReg === '' && $ownType === '' && $drvId) {
            $drvStmt->execute([':id' => $drvId, ':cid' => $cid]);
            if ($row = $drvStmt->fetch()) {
              $ownReg  = $row['reg_no'] ?? '';
              $ownType = $row['vtype'] ?? '';
            }
          }
          if ($ownReg !== '' || $ownType !== '') {
            $vehRegToSave  = $ownReg !== ''  ? strtoupper($ownReg) : null;
            $vehTypeToSave = $ownType !== '' ? $ownType : null;
          }
        }

        $insBV->execute([
          ':bid' => $bid,
          ':vid' => $vehIdOrNull,
          ':vt'  => $vehTypeToSave,
          ':vr'  => $vehRegToSave,
          ':did' => ($drvId ?: null),
          ':dp'  => $dp,
          ':cp'  => $cp,
          ':seq' => $seq++,
        ]);

        $sum_client += $cp;
        $sum_driver += $dp;
      }

      // Update totals (client/driver)
      $pdo->prepare("UPDATE bookings SET total_client_price = :tc, total_driver_price = :td WHERE id = :id")
          ->execute([':tc' => $sum_client, ':td' => $sum_driver, ':id' => $bid]);

      $pdo->commit();
      audit_log('booking.create', 'booking', $bid, ['ref' => $ref]);
      redirect('list.php');
    }
  } catch (Throwable $e) {
    if ($pdo->inTransaction()) $pdo->rollBack();
    $errors[] = (defined('APP_ENV') && APP_ENV === 'dev') ? $e->getMessage() : 'Unexpected error while creating booking.';
  }
}

/* ---------- View ---------- */
include dirname(__DIR__, 2) . '/includes/header.php';

// JS data blobs
$JS_VEHICLES   = json_encode($vehicles, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$JS_DRIVERS    = json_encode($drivers,  JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// Map driver_id -> {reg_no, type}
$ownMap = [];
foreach ($drivers as $d) {
  $ownMap[(int)$d['id']] = [
    'reg_no' => (string)$d['own_vehicle_reg_no'],
    'type'   => (string)$d['own_vehicle_type'],
  ];
}
$JS_DRIVER_OWN = json_encode($ownMap, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
?>
<div class="d-flex justify-content-between align-items-center mb-3">
  <h1 class="h4 mb-0">Add Booking</h1>
  <a href="list.php" class="btn btn-outline-secondary">Back</a>
</div>

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

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

      <div class="row g-3">
        <div class="col-md-3">
          <label class="form-label">Booking Ref</label>
          <input class="form-control" name="booking_ref" value="<?= e($_POST['booking_ref'] ?? $suggestedRef) ?>">
          <div class="form-text">Leave blank to auto-generate (e.g. BHC-<?= e(date('dmY')) ?>-######)</div>
        </div>
        <div class="col-md-3">
          <label class="form-label">Type</label>
          <select name="booking_type" class="form-select">
            <option <?= (($_POST['booking_type'] ?? '')==='Transfer')?'selected':''; ?>>Transfer</option>
            <option <?= (($_POST['booking_type'] ?? '')==='As Directed')?'selected':''; ?>>As Directed</option>
          </select>
        </div>
        <div class="col-md-3">
          <label class="form-label">Hours (if AD)</label>
          <input type="number" step="0.5" class="form-control" name="hours" value="<?= e($_POST['hours'] ?? '') ?>">
        </div>
        <div class="col-md-3">
          <label class="form-label">Partner (optional)</label>
          <select name="partner_id" class="form-select">
            <option value="">—</option>
            <?php foreach ($partners as $p): ?>
              <option value="<?= (int)$p['id'] ?>" <?= ((int)($_POST['partner_id'] ?? 0)===(int)$p['id'])?'selected':''; ?>>
                <?= e($p['name']) ?>
              </option>
            <?php endforeach; ?>
          </select>
        </div>

        <div class="col-md-3">
          <label class="form-label">Corporate Client (optional)</label>
          <select name="corporate_id" class="form-select">
            <option value="">—</option>
            <?php foreach ($corporates as $c): ?>
              <option value="<?= (int)$c['id'] ?>" <?= ((int)($_POST['corporate_id'] ?? 0)===(int)$c['id'])?'selected':''; ?>>
                <?= e($c['name']) ?>
              </option>
            <?php endforeach; ?>
          </select>
          <div class="form-text">Select if this booking is from a corporate account.</div>
        </div>

        <div class="col-md-3">
          <label class="form-label">Client Name</label>
          <input class="form-control" name="client_name" value="<?= e($_POST['client_name'] ?? '') ?>">
        </div>
        <div class="col-md-3">
          <label class="form-label">Client Phone</label>
          <input class="form-control" name="client_phone" value="<?= e($_POST['client_phone'] ?? '') ?>">
        </div>
        <div class="col-md-3">
          <label class="form-label">Client Email</label>
          <input type="email" class="form-control" name="client_email" value="<?= e($_POST['client_email'] ?? '') ?>">
        </div>

        <div class="col-md-3">
          <label class="form-label">Pickup Date <span class="text-danger">*</span></label>
          <input type="date" class="form-control" name="pickup_date" required value="<?= e($_POST['pickup_date'] ?? '') ?>">
        </div>
        <div class="col-md-3">
          <label class="form-label">Pickup Time <span class="text-danger">*</span></label>
          <input type="time" class="form-control" name="pickup_time" required value="<?= e($_POST['pickup_time'] ?? '') ?>">
        </div>
        <div class="col-md-6">
          <label class="form-label">Pickup Address</label>
          <input class="form-control" name="pickup_address" value="<?= e($_POST['pickup_address'] ?? '') ?>">
        </div>
        <div class="col-md-6">
          <label class="form-label">Via</label>
          <input class="form-control" name="via" value="<?= e($_POST['via'] ?? '') ?>">
        </div>
        <div class="col-md-6">
          <label class="form-label">Dropoff Address</label>
          <input class="form-control" name="dropoff_address" value="<?= e($_POST['dropoff_address'] ?? '') ?>">
        </div>

        <div class="col-md-3">
          <label class="form-label">Flight Number (optional)</label>
          <input class="form-control" name="flight_number" value="<?= e($_POST['flight_number'] ?? '') ?>">
        </div>
        <div class="col-md-3">
          <label class="form-label">Commission Amount (£)</label>
          <input type="number" step="0.01" class="form-control" name="partner_commission_amount" value="<?= e($_POST['partner_commission_amount'] ?? '0') ?>">
        </div>

        <div class="col-md-3">
          <label class="form-label">Passengers</label>
          <input type="number" class="form-control" name="pax_count" value="<?= e($_POST['pax_count'] ?? '0') ?>">
        </div>
        <div class="col-md-3">
          <label class="form-label">Luggage</label>
          <input type="number" class="form-control" name="luggage_count" value="<?= e($_POST['luggage_count'] ?? '0') ?>">
        </div>

        <div class="col-12">
          <label class="form-label">Notes</label>
          <textarea class="form-control" name="notes" rows="2"><?= e($_POST['notes'] ?? '') ?></textarea>
        </div>
      </div>

      <hr>
      <h5 class="mb-2">Vehicles & Drivers (optional)</h5>
      <p class="text-muted small mb-2">
        Select a <strong>Driver</strong> first. If they have an own vehicle on their profile, it auto-fills here.
        You can still choose a different company vehicle from the dropdown.
      </p>

      <div id="bvRows" class="mb-2"></div>
      <button type="button" class="btn btn-outline-secondary" id="btnAddRow">+ Add Vehicle</button>

      <div class="mt-3">
        <button class="btn btn-dark" type="submit">Create Booking</button>
      </div>
    </form>
  </div>
</div>

<script>
/* ===== Data sources for row builders ===== */
const VEHICLES   = <?= $JS_VEHICLES ?>;
const DRIVERS    = <?= $JS_DRIVERS  ?>;
const DRIVER_OWN = <?= $JS_DRIVER_OWN ?>;

/* ===== Utilities ===== */
function escapeHtml(s) {
  if (s === null || s === undefined) return '';
  return String(s)
    .replace(/&/g,'&amp;')
    .replace(/</g,'&lt;')
    .replace(/>/g,'&gt;')
    .replace(/"/g,'&quot;')
    .replace(/'/g,'&#39;');
}

function buildVehicleOptions(selectedId) {
  let html = '<option value="">—</option>';
  for (const v of VEHICLES) {
    const sel = (selectedId && String(selectedId) === String(v.id)) ? ' selected' : '';
    html += `<option value="${v.id}"${sel}>${escapeHtml(v.reg_no)} (${escapeHtml(v.type)})</option>`;
  }
  return html;
}
function buildDriverOptions(selectedId) {
  let html = '<option value="">—</option>';
  for (const d of DRIVERS) {
    const sel = (selectedId && String(selectedId) === String(d.id)) ? ' selected' : '';
    html += `<option value="${d.id}"${sel}>${escapeHtml(d.name)}</option>`;
  }
  return html;
}

/* ===== Row builder ===== */
function addRow(data) {
  data = data || {};
  const wrap = document.createElement('div');
  wrap.className = 'row g-2 align-items-end bv-row mt-1';

  wrap.innerHTML = `
    <div class="col-md-3">
      <label class="form-label">Driver</label>
      <select class="form-select bv-driver" name="bv_driver_id[]">
        ${buildDriverOptions(data.driver_id)}
      </select>
    </div>
    <div class="col-md-3">
      <label class="form-label">Vehicle</label>
      <select class="form-select bv-vehicle" name="bv_vehicle_id[]">
        ${buildVehicleOptions(data.vehicle_id)}
      </select>
      <div class="form-text text-success small bv-own-hint" style="display:none;"></div>
      <input type="hidden" name="bv_vehicle_reg_no[]" class="bv-reg" value="">
      <input type="hidden" name="bv_vehicle_type[]" class="bv-type" value="">
    </div>
    <div class="col-md-2">
      <label class="form-label">Client £</label>
      <input type="number" step="0.01" class="form-control" name="bv_client_price[]" value="${data.client_price ?? ''}">
    </div>
    <div class="col-md-2">
      <label class="form-label">Driver £</label>
      <input type="number" step="0.01" class="form-control" name="bv_driver_price[]" value="${data.driver_price ?? ''}">
    </div>
    <div class="col-md-2">
      <button type="button" class="btn btn-outline-danger w-100 btn-remove-row">Remove</button>
    </div>
  `;

  const selDriver  = wrap.querySelector('.bv-driver');
  const selVehicle = wrap.querySelector('.bv-vehicle');
  const hint       = wrap.querySelector('.bv-own-hint');
  const hidReg     = wrap.querySelector('.bv-reg');
  const hidType    = wrap.querySelector('.bv-type');

  function applyOwnVehicleIfAny() {
    const drvId = selDriver.value;
    const own = DRIVER_OWN && DRIVER_OWN[drvId] ? DRIVER_OWN[drvId] : null;
    if (own && (own.reg_no || own.type)) {
      selVehicle.value = '';
      hidReg.value  = own.reg_no || '';
      hidType.value = own.type   || '';
      hint.style.display = 'block';
      hint.textContent = 'Own vehicle applied: '
        + (own.reg_no ? own.reg_no : 'Reg N/A')
        + (own.type ? ' (' + own.type + ')' : '');
    } else {
      if (!selVehicle.value) {
        hidReg.value  = '';
        hidType.value = '';
      }
      hint.style.display = 'none';
      hint.textContent   = '';
    }
  }

  selDriver.addEventListener('change', applyOwnVehicleIfAny);
  selVehicle.addEventListener('change', function() {
    if (selVehicle.value) {
      hidReg.value  = '';
      hidType.value = '';
      hint.style.display = 'none';
      hint.textContent   = '';
    } else {
      applyOwnVehicleIfAny();
    }
  });

  document.getElementById('bvRows').appendChild(wrap);

  if (data.driver_id) applyOwnVehicleIfAny();
}

/* ===== Init ===== */
document.addEventListener('DOMContentLoaded', function() {
  addRow();

  document.getElementById('btnAddRow').addEventListener('click', function() {
    addRow();
  });

  document.getElementById('bvRows').addEventListener('click', function(e) {
    const btn = e.target.closest('.btn-remove-row');
    if (!btn) return;
    const row = btn.closest('.bv-row');
    if (row) row.remove();
  });
});
</script>

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