<?php
declare(strict_types=1);
header('Content-Type: application/json');

if (file_exists('../../../../' . $_REQUEST['tenant'] . '/config.php')) {
    require_once('../../../../' . $_REQUEST['tenant'] . '/config.php');
}
if (file_exists('/config.php')) {
    require_once('/config.php');
}

$con = $GLOBALS['con'] ?? null;
if (!$con) { echo json_encode(['status'=>'error','message'=>'DB not connected']); exit; }
$con->set_charset('utf8mb4');

$invNo = (int)($_GET['invNo'] ?? $_POST['invNo'] ?? 0);
if ($invNo <= 0) { echo json_encode(['status'=>'error','message'=>'Invalid invNo']); exit; }

function is_json($s){ if(!is_string($s)||$s==='') return false; json_decode($s); return json_last_error()===JSON_ERROR_NONE; }
function try_unserialize($s){
  if (!is_string($s) || $s==='') return null;
  if (!preg_match('/^(?:a|s|i|d|b|O|C|R|N):/',$s)) return null;
  $v = @unserialize($s, ['allowed_classes'=>false]);
  return ($v!==false || $s==='b:0;') ? $v : null;
}
function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); }

/* invoice */
$stmt = $con->prepare("SELECT * FROM invoices WHERE invNo=? LIMIT 1");
$stmt->bind_param('i',$invNo);
$stmt->execute();
$res = $stmt->get_result();
$stmt->close();
$inv = $res->fetch_assoc();
if (!$inv) { echo json_encode(['status'=>'error','message'=>'Invoice not found']); exit; }

/* core */
$clientId       = (int)($inv['client'] ?? 0);
$agent_number   = (int)($inv['agent']  ?? 0);
$broker_number  = (int)($inv['broker'] ?? 0);
$target         = (string)($inv['target'] ?? 'client');
$notes          = (string)($inv['notes'] ?? '');
$vatrate        = (float)($inv['vatrate'] ?? 0);
$tsDate         = (int)($inv['date'] ?? 0);
$purchase_order = (string)($inv['purchase_order'] ?? '');
$inv_commission = is_numeric($inv['commission'] ?? null) ? (float)$inv['commission'] : 0.0;

/* client row (includes commission config source) */
$client = [
  'clientname'=>'','postcode'=>'',
  'commission'=>null,'comType'=>0,
  'broker_number'=>0,'agent_number'=>0,'contract_number'=>'',
  'billing_name'=>'','billing1'=>'','billing2'=>'','billing_town'=>'','billing_county'=>'','billing_postcode'=>''
];
if ($clientId>0){
  $q=$con->prepare(
    "SELECT clientname,postcode,commission,comType,broker_number,agent_number,contract_number,
            billing_name,billing1,billing2,billing_town,billing_county,billing_postcode
     FROM clientdetails WHERE clientnumber=? LIMIT 1");
  $q->bind_param('i',$clientId);
  $q->execute(); $r=$q->get_result(); $q->close();
  if ($row=$r->fetch_assoc()){ foreach($row as $k=>$v){ $client[$k]=$v; } }
}
if ($broker_number<=0) $broker_number = (int)$client['broker_number'];
if ($agent_number <=0) $agent_number  = (int)$client['agent_number'];

/* address */
$addrRaw = $inv['address'] ?? '';
$addrArr = try_unserialize($addrRaw);
if ($addrArr===null) $addrArr = is_json($addrRaw) ? json_decode($addrRaw,true) : [];
if (!is_array($addrArr)) $addrArr = [];

$billing_name     = $addrArr['billing_name']     ?? $client['billing_name'];
$billing1         = $addrArr['billing1']         ?? $client['billing1'];
$billing2         = $addrArr['billing2']         ?? $client['billing2'];
$billing_town     = $addrArr['billing_town']     ?? $client['billing_town'];
$billing_county   = $addrArr['billing_county']   ?? $client['billing_county'];
$billing_postcode = $addrArr['billing_postcode'] ?? $client['billing_postcode'];
$contract_number = (string)($client['contract_number'] ?? '');
if ($purchase_order==='' && isset($addrArr['purchaseOrder'])) $purchase_order = (string)$addrArr['purchaseOrder'];

/* items */
$itemsRaw = $inv['items'] ?? '[]';
$items = [];
$legacyItemsLoaded = false;

$ser = try_unserialize($itemsRaw);

if (is_array($ser)) {
    // Correct stored format already
    $items = $ser;
} elseif (is_string($ser) && is_json($ser)) {
    // Legacy: serialized JSON string
    $items = json_decode($ser, true) ?: [];
    $legacyItemsLoaded = true;
} elseif (is_json($itemsRaw)) {
    // Legacy: plain JSON
    $items = json_decode($itemsRaw, true) ?: [];
    $legacyItemsLoaded = true;
}

$normItems = [];
foreach ($items as $it) {
    $normItems[] = [
        'service'  => (string)($it['service']  ?? ''),
        'notes'    => (string)($it['notes']    ?? ''),
        'rate'     => (string)($it['rate']     ?? '0'),
        'quantity' => (string)($it['quantity'] ?? '1'),
    ];
}

/* self-heal legacy item storage */
if ($legacyItemsLoaded && !empty($normItems)) {
    $cleanItems = serialize($normItems);

    $up = $con->prepare("UPDATE invoices SET items = ? WHERE invNo = ? LIMIT 1");
    $up->bind_param('si', $cleanItems, $invNo);
    $up->execute();
    $up->close();

    // Keep local copy aligned with what has now been stored
    $inv['items'] = $cleanItems;
}

/* totals (net|vat) */
$net=0.0; $vat=0.0;
$totalsRaw = (string)($inv['totals'] ?? '');
if (strpos($totalsRaw,'|')!==false){ [$n,$v]=explode('|',$totalsRaw,2); $net=(float)$n; $vat=(float)$v; }
else {
  foreach($normItems as $it){
    $r=(float)str_replace([',',' '],'',$it['rate']);
    $q=(float)str_replace([',',' '],'',$it['quantity']); if ($q<=0) $q=1;
    $net += $r*$q;
  }
  $vat = $net * $vatrate;
}

/* names: broker + agent */
$broker_name = '';
if ($broker_number>0){
  $br=$con->prepare("SELECT broker_name FROM brokers WHERE broker_number=? LIMIT 1");
  $br->bind_param('i',$broker_number);
  $br->execute(); $brr=$br->get_result(); $br->close();
  if ($b=$brr->fetch_assoc()) $broker_name = (string)$b['broker_name'];
}
$agent_name = '';
if ($agent_number>0){
  $ar=$con->prepare("SELECT agent_name FROM agents WHERE agent_number=? LIMIT 1");
  $ar->bind_param('i',$agent_number);
  $ar->execute(); $arr=$ar->get_result(); $ar->close();
  if ($a=$arr->fetch_assoc()) $agent_name = (string)$a['agent_name'];
}

/* commission config:
   - initial_amount: invoices.commission
   - source for rule: clientdetails.commission + clientdetails.comType
   - type: 0=percentage, 1=fixed
   Final amount calculated client-side on NET. */
$commissionCfg = null;
if ($broker_number>0){
  $cVal = is_numeric($client['commission']) ? (float)$client['commission'] : 0.0;
  $cTyp = (int)($client['comType'] ?? 0);
  if ($cTyp === 0) {
    $commissionCfg = ['type'=>0, 'label'=>" ({$cVal}%)", 'value'=>$cVal, 'initial_amount'=>$inv_commission];
  } else {
    $commissionCfg = ['type'=>1, 'label'=>" (fixed)", 'value'=>$cVal, 'initial_amount'=>$inv_commission];
  }
}

$is_broker = ($target==='broker') || ($broker_number>0);
$is_agent  = ($target==='agent')  || ($agent_number>0);

/* blocks */
$billingHtml =
  "<div><strong>Name:</strong> ".h($billing_name)."</div>".
  "<div><strong>Billing1:</strong> ".h($billing1)."</div>".
  "<div><strong>Billing2:</strong> ".h($billing2)."</div>".
  "<div><strong>Town:</strong> ".h($billing_town)."</div>".
  "<div><strong>County:</strong> ".h($billing_county)."</div>".
  "<div><strong>Postcode:</strong> ".h($billing_postcode)."</div>";

$accountHtml =
  "<div><strong>Contract:</strong> ".h($contract_number)."</div>".
  "<div><strong>Client:</strong> ".h($client['clientname'])."</div>";
if ($broker_number>0) $accountHtml .= "<div><strong>Broker:</strong> ".h($broker_name)."</div>";
if ($agent_number>0)  $accountHtml .= "<div><strong>Agent:</strong> ".h($agent_name)."</div>";

echo json_encode([
  'status'                => 'success',
  'clientnumber'          => $clientId,
  'company'               => $client['clientname'],
  'postcode'              => $client['postcode'],
  'invoicenumber'         => $invNo,
  'invoice_date_ddmmyyyy' => $tsDate ? date('d-m-Y',$tsDate) : date('d-m-Y'),
  'purchase_order'        => $purchase_order,
  'billing'               => $billingHtml,
  'account'               => $accountHtml,
  'items'                 => $normItems,
  'broker_number'         => $broker_number,
  'agent_number'          => $agent_number,
  'is_broker'             => (bool)$is_broker,
  'is_agent'              => (bool)$is_agent,
  'commission'            => $commissionCfg,
  'notes'                 => $notes,
  'totals'                => ['net'=>$net, 'vat'=>$vat, 'vatrate'=>$vatrate]
]);
