<?php
// /edenrms/pages/payment_manager_api.php
declare(strict_types=1);

require_once __DIR__ . '/../includes/auth.php';
ec_require_login();

require_once __DIR__ . '/../includes/db.php';
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn->set_charset('utf8mb4');

/* ---------- helpers ---------- */
function out($data){ header('Content-Type: application/json'); echo json_encode($data); exit; }
function fail(int $code, string $msg){ http_response_code($code); out(['ok'=>false,'error'=>$msg]); }
function asf($a,$k,$d=0.0){ return (float)($a[$k]??$d); }
function asn($a,$k,$d=0){ return (int)($a[$k]??$d); }
function ass($a,$k,$d=''){ $v=$a[$k]??$d; return is_string($v)?$v:$d; }

function read_payload(): array {
  $ctype = $_SERVER['CONTENT_TYPE'] ?? '';
  $raw = file_get_contents('php://input') ?: '';

  // JSON body
  if (stripos($ctype, 'application/json') !== false && $raw !== '') {
    $j = json_decode($raw, true);
    if (is_array($j)) return $j;
  }

  // Fallback: payload=<json>
  if (isset($_POST['payload'])) {
    $j = json_decode($_POST['payload'], true);
    if (is_array($j)) return $j;
  }

  // Last resort: plain POST fields
  return $_POST ?? [];
}

/* ---------- tiny dal ---------- */
function getStandardPlan(mysqli $db, int $course_id): array {
  $s=$db->prepare("SELECT id, plan_name, course_fee_lkr, registration_fee_lkr, certificate_fee_usd
                   FROM payment_plans
                   WHERE course_id=? AND plan_type='standard'
                   ORDER BY id DESC LIMIT 1");
  $s->bind_param('i',$course_id); $s->execute();
  $row=$s->get_result()->fetch_assoc(); $s->close();
  return $row ? [
    'plan_id'=>(int)$row['id'],
    'plan_name'=>$row['plan_name']??'Standard',
    'course_fee_lkr'=>(float)$row['course_fee_lkr'],
    'registration_fee_lkr'=>(float)$row['registration_fee_lkr'],
    'certificate_fee_usd'=>(float)$row['certificate_fee_usd'],
  ] : ['plan_id'=>0,'plan_name'=>'Standard','course_fee_lkr'=>0,'registration_fee_lkr'=>0,'certificate_fee_usd'=>0];
}

$action = $_GET['action'] ?? ($_POST['action'] ?? '');

try {

  /* ------------------ Course overview (top meta) ------------------ */
  if ($action === 'course_overview'){
    $course_id = (int)($_GET['course_id'] ?? 0);
    if(!$course_id) fail(400,'course_id required');

    $s=$conn->prepare("SELECT * FROM courses WHERE id=? LIMIT 1");
    $s->bind_param('i',$course_id); $s->execute();
    $c=$s->get_result()->fetch_assoc() ?: []; $s->close();

    $duration = $c['duration'] ?? ($c['months'] ?? null);
    if (is_numeric($duration)) $duration .= ' months';

    $std = getStandardPlan($conn,$course_id);
    $meta = [
      'course_name' => $c['course_name'] ?? ('Course #'.$course_id),
      'duration'    => $duration ?: '—',
      'currency'    => 'LKR',
      'standard_total_lkr' => (float)$std['course_fee_lkr'] + (float)$std['registration_fee_lkr'],
    ];
    out(['meta'=>$meta,'standard'=>$std]);
  }

  /* ------------------ Standard fee ------------------ */
  if ($action === 'get_standard_fee'){
    $course_id = (int)($_GET['course_id'] ?? 0);
    if(!$course_id) fail(400,'course_id required');
    out(getStandardPlan($conn,$course_id));
  }

  if ($action === 'save_standard_fee') {
    $p = read_payload();
    if (!is_array($p)) fail(400, 'Invalid JSON');

    $course_id = asn($p, 'course_id', 0);
    if (!$course_id) fail(400, 'course_id required');

    $plan_name = trim(ass($p, 'plan_name', 'Standard'));
    $cFee = asf($p, 'course_fee_lkr', 0);
    $rFee = asf($p, 'registration_fee_lkr', 0);
    $uFee = asf($p, 'certificate_fee_usd', 0);

    // upsert payment_plans (plan_type='standard')
    $s = $conn->prepare("SELECT id FROM payment_plans WHERE course_id=? AND plan_type='standard' ORDER BY id DESC LIMIT 1");
    $s->bind_param('i', $course_id); $s->execute();
    $row = $s->get_result()->fetch_assoc(); $s->close();

    if ($row) {
      $id = (int)$row['id'];
      $u = $conn->prepare("UPDATE payment_plans
                           SET plan_name=?, course_fee_lkr=?, registration_fee_lkr=?, certificate_fee_usd=?
                           WHERE id=?");
      $u->bind_param('sdddi', $plan_name, $cFee, $rFee, $uFee, $id);
      $u->execute(); $u->close();
      out(['ok' => true, 'plan_id' => $id]);
    } else {
      $i = $conn->prepare("INSERT INTO payment_plans
        (course_id, plan_name, course_fee_lkr, registration_fee_lkr, certificate_fee_usd, option_type, plan_type, status)
        VALUES (?,?,?,?,?,'Standard','standard','Active')");
      $i->bind_param('isddd', $course_id, $plan_name, $cFee, $rFee, $uFee);
      $i->execute(); $id = $i->insert_id; $i->close();
      out(['ok' => true, 'plan_id' => $id]);
    }
  }

  /* ------------------ Discount offers ------------------ */
if ($action === 'get_discount_offers'){
  $course_id = (int)($_GET['course_id'] ?? 0);
  if(!$course_id) fail(400,'course_id required');

  $std = getStandardPlan($conn,$course_id);
  $base = (float)$std['course_fee_lkr'] + (float)$std['registration_fee_lkr'];

  $rows=[];
  $q=$conn->prepare("SELECT code,label,offer_type,amount_lkr,status,sort_order
                     FROM course_discounts
                     WHERE course_id=? ORDER BY sort_order ASC, id ASC");
  $q->bind_param('i',$course_id);
  $q->execute();
  $rs=$q->get_result();

  while($r=$rs->fetch_assoc()){
    $amt = (float)($r['amount_lkr'] ?? 0);
    $pct = ($base>0) ? round(($amt/$base)*100,2) : 0.0;

    $rows[] = [
      'offer_name'       => $r['label'] ?? '',
      'offer_type'       => (($r['offer_type'] ?? 'full') === 'part') ? 'part' : 'full',
      'discount_pct'     => $pct,
      'payable_fee_lkr'  => max(0.0, $base - $amt),
      'remarks'          => '',
      'status'           => (string)($r['status'] ?? 'active'),
      'sort_order'       => (int)($r['sort_order'] ?? 0),
    ];
  }

  $q->close();
  out(['rows'=>$rows]);
}


if ($action === 'save_discount_offers'){
  $p = read_payload();
  if(!is_array($p)) fail(400,'Invalid JSON');

  $course_id = asn($p,'course_id',0);
  if(!$course_id) fail(400,'course_id required');

  $std = getStandardPlan($conn,$course_id);
  $base = (float)$std['course_fee_lkr'] + (float)$std['registration_fee_lkr'];
  $offers = $p['offers'] ?? [];

  $conn->begin_transaction();
  $del=$conn->prepare("DELETE FROM course_discounts WHERE course_id=?");
  $del->bind_param('i',$course_id); 
  $del->execute(); 
  $del->close();

  if(!empty($offers)){
    $ins=$conn->prepare("INSERT INTO course_discounts
      (course_id, code, label, offer_type, amount_lkr, is_default, status, sort_order)
      VALUES (?,?,?,?,?,0,?,?)");

    foreach($offers as $o){
      $name = trim(ass($o,'offer_name',''));
      if($name==='') continue;

      $type = (ass($o,'offer_type','full') === 'part') ? 'part' : 'full';
      $pct  = max(0.0,min(100.0, asf($o,'discount_pct',0)));
      $payable = asf($o,'payable_fee_lkr', ($base>0 ? $base*(1-$pct/100):0));
      $discountAmt = max(0.0, $base - $payable);
      $code = substr(preg_replace('/[^A-Za-z0-9]+/','', $name),0,50) ?: 'DISC';

      $status = (ass($o,'status','active')==='inactive') ? 'inactive' : 'active';
      $sort   = asn($o,'sort_order',0);

      $ins->bind_param('isssdsi', $course_id, $code, $name, $type, $discountAmt, $status, $sort);
      $ins->execute();
    }
    $ins->close();
  }

  $conn->commit();
  out(['ok'=>true]);
}

  /* ------------------ Installment plans ------------------ */
if ($action === 'get_installment_plans'){
  $course_id = (int)($_GET['course_id'] ?? 0);
  if(!$course_id) fail(400,'course_id required');

  $rows=[];
  $q=$conn->prepare("SELECT id, plan_name, months, status, certificate_fee_usd
                     FROM payment_plans
                     WHERE course_id=? AND plan_type='installment'
                     ORDER BY id ASC");

  $q->bind_param('i',$course_id);
  $q->execute();
  $rs=$q->get_result();

  while($p=$rs->fetch_assoc()){
    $cnt=0;
$courseSum=0.0;
$regSum=0.0;
    $pid=(int)$p['id'];

    $qq=$conn->prepare("SELECT course_fee_lkr, registration_fee_lkr
                        FROM payment_plan_installments
                        WHERE plan_id=?");
    $qq->bind_param('i',$pid);
    $qq->execute();
    $rr=$qq->get_result();

    while($L=$rr->fetch_assoc()){
      $cnt++;
      $courseSum += (float)$L['course_fee_lkr'];
$regSum += (float)$L['registration_fee_lkr'];
    }
    $qq->close();

    $rows[] = [
      'id' => $pid,
      'plan_name' => $p['plan_name'] ?? '',
      'installments_count' => $cnt,
      'total_fee_lkr' => $courseSum,
'registration_fee_lkr' => $regSum,
      'certificate_fee_usd' => (float)($p['certificate_fee_usd'] ?? 0),
      'duration_months' => isset($p['months']) ? (int)$p['months'] : null,
      'remarks' => '',
      'status' => ((string)($p['status'] ?? 'Active') === 'Inactive') ? 'inactive' : 'active',
      'sort_order' => 0
    ];
  }

  $q->close();
  out(['rows'=>$rows]);
}

  if ($action === 'get_installment_plan'){
    $plan_id = (int)($_GET['plan_id'] ?? 0);
    if(!$plan_id) fail(400,'plan_id required');

    $s=$conn->prepare("SELECT id, course_id, plan_name, months, status, certificate_fee_usd
                   FROM payment_plans WHERE id=? AND plan_type='installment' LIMIT 1");

    $s->bind_param('i',$plan_id); $s->execute();
    $p=$s->get_result()->fetch_assoc(); $s->close();
    if(!$p) fail(400,'Plan not found');

   $lines=[];
$q=$conn->prepare("SELECT installment_no, due_date, course_fee_lkr, registration_fee_lkr, '' AS notes
                   FROM payment_plan_installments
                   WHERE plan_id=? ORDER BY installment_no ASC, id ASC");
$q->bind_param('i',$plan_id);
$q->execute();
$rs=$q->get_result();

$total = 0.0;
$regTotal = 0.0;

while($r=$rs->fetch_assoc()){
  $courseAmt = (float)$r['course_fee_lkr'];
  $regAmt    = (float)$r['registration_fee_lkr'];

  $lines[]=[
    'installment_no'=>(int)$r['installment_no'],
    'due_date'=>$r['due_date'],
    'amount_lkr'=>$courseAmt + $regAmt,
    'notes'=>''
  ];

  $total += $courseAmt;
  $regTotal += $regAmt;
}
$q->close();

    out([
      'id'=>(int)$p['id'],
      'course_id'=>(int)$p['course_id'],
      'plan_name'=>$p['plan_name']??'',
      'installments_count'=>max(1,count($lines)),
      'total_fee_lkr'=>$total,
'registration_fee_lkr'=>$regTotal,
      'certificate_fee_usd' => (float)($p['certificate_fee_usd'] ?? 0),
      'duration_months'=> (int)($p['months'] ?? 0),
      'remarks'=>'',
      'status'=> (string)$p['status']==='Inactive' ? 'inactive' : 'active',
      'sort_order'=>0,
      'lines'=>$lines
    ]);
  }



  if ($action === 'save_installment_plan') {
    $p = read_payload();
    if (!is_array($p)) fail(400,'Invalid JSON');

    $id         = asn($p,'id',0);
    $course_id  = asn($p,'course_id',0);
    if (!$course_id) fail(400,'course_id required');

    $name   = trim(ass($p,'plan_name',''));
    $icount = max(1, asn($p,'installments_count',1));
    $total  = asf($p,'total_fee_lkr',0);
    $months = asn($p,'duration_months',0);
    $status = (ass($p,'status','active')==='inactive') ? 'Inactive' : 'Active';
    $lines  = $p['lines'] ?? [];
    $certUsd = asf($p,'certificate_fee_usd',0);
    $regFee = asf($p,'registration_fee_lkr',0);


    // validate sum == total
    $sum = 0.0; 
    $regFee = asf($p,'registration_fee_lkr',0);
foreach ($lines as $L) { 
  $sum += (float)($L['amount_lkr'] ?? 0); 
}

$grandTotal = $total + $regFee;

if (abs($sum - $grandTotal) > 0.005) {
  fail(400, 'Validation failed: installments sum must equal total fee + registration fee.');
}

    $conn->begin_transaction();

    if ($id > 0) {
      // UPDATE header
      $u = $conn->prepare("UPDATE payment_plans
                     SET plan_name=?, months=?, status=?, certificate_fee_usd=?
                     WHERE id=? AND course_id=? AND plan_type='installment'");
try {
  $u->bind_param('sisdii', $name, $months, $status, $certUsd, $id, $course_id);
} catch(Throwable $e){
  fail(500, 'UPDATE header bind_param: '.$e->getMessage());
}

$u->execute();
$u->close();


      // re-write lines
      $del = $conn->prepare("DELETE FROM payment_plan_installments WHERE plan_id=?");
      $del->bind_param('i', $id); $del->execute(); $del->close();

      $ins = $conn->prepare("INSERT INTO payment_plan_installments
        (plan_id, installment_no, due_date, course_fee_lkr, registration_fee_lkr, certificate_fee_usd)
        VALUES (?,?,?,?,?,0)");
      foreach ($lines as $L) {
        $no  = (int)($L['installment_no'] ?? 0);
        $due = ($L['due_date'] ?? null) ?: null;
        $lineTotal = (float)($L['amount_lkr'] ?? 0);
$regPart   = ($icount > 0) ? ($regFee / $icount) : 0;
$amt       = max(0.0, $lineTotal - $regPart);
        $ins->bind_param('iisdd', $id, $no, $due, $amt, $regPart);
        $ins->execute();
      }
      $ins->close();

    } else {
      // INSERT header
      $i = $conn->prepare("INSERT INTO payment_plans
  (course_id, plan_name, plan_type, months, status, option_type, certificate_fee_usd)
  VALUES (?,?, 'installment', ?, ?, 'Installment', ?)");
try {
  $i->bind_param('isisd', $course_id, $name, $months, $status, $certUsd);
} catch(Throwable $e){
  fail(500, 'INSERT header bind_param: '.$e->getMessage());
}

$i->execute();
$newId = $i->insert_id;
$i->close();


      // INSERT lines
      $ins = $conn->prepare("INSERT INTO payment_plan_installments
        (plan_id, installment_no, due_date, course_fee_lkr, registration_fee_lkr, certificate_fee_usd)
        VALUES (?,?,?,?,?,0)");
      foreach ($lines as $L) {
  $no  = (int)($L['installment_no'] ?? 0);
  $due = ($L['due_date'] ?? null) ?: null;
  $amt = (float)($L['amount_lkr'] ?? 0);

  try {
    $regPart = ($icount > 0) ? ($regFee / $icount) : 0;
$ins->bind_param('iisdd', $newId, $no, $due, $amt, $regPart);
  } catch(Throwable $e){
    fail(500, 'INSERT lines bind_param: '.$e->getMessage());
  }

  $ins->execute();
}
      $ins->close();
    }

    $conn->commit();
    out(['ok'=>true]);
  }

  if ($action === 'delete_installment_plan'){
    $plan_id = (int)($_POST['plan_id'] ?? 0);
    if(!$plan_id) fail(400,'plan_id required');
    $d=$conn->prepare("DELETE FROM payment_plans WHERE id=? AND plan_type='installment'");
    $d->bind_param('i',$plan_id); $d->execute(); $d->close();
    out(['ok'=>true]);
  }

  http_response_code(404);
  echo "Unknown action";
} catch(Throwable $e){
  try{ $conn->rollback(); } catch(Throwable $e2){}
  fail(500, $e->getMessage());
}
