<?php
require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/../includes/auth.php';
require_once __DIR__ . '/../includes/db.php';
require_login();
header('Content-Type: application/json');
$mysqli = db();
$action = $_GET['action'] ?? $_POST['action'] ?? 'list';

function ensure_admin_pay(){ if (!has_role(['admin','super_admin'])) json_response(['message'=>'Forbidden'], 403); }

function ym_bounds($y,$m){
  $first = sprintf('%04d-%02d-01', $y, $m);
  $last = date('Y-m-t', strtotime($first));
  return [$first, $last];
}

switch ($action) {
  case 'list':
    $month = (int)($_GET['month'] ?? date('n'));
    $year = (int)($_GET['year'] ?? date('Y'));
    $stmt = $mysqli->prepare('SELECT p.id, p.employee_id, e.full_name AS employee_name, p.period_month, p.period_year, p.gross_salary, p.total_incentives, p.total_allowances, p.total_advances, p.total_deductions, p.net_salary, p.paid_on, p.generated_on FROM salary_payroll p LEFT JOIN employees e ON e.id=p.employee_id WHERE p.period_month=? AND p.period_year=? ORDER BY e.full_name');
    $stmt->bind_param('ii',$month,$year); $stmt->execute(); $res=$stmt->get_result();
    $data=[]; while($r=$res->fetch_assoc()){ $data[]=$r; }
    json_response(['data'=>$data]);
    break;

  case 'generate':
    ensure_admin_pay(); if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message'=>'Invalid CSRF'],400);
    $month=(int)($_POST['month'] ?? date('n')); $year=(int)($_POST['year'] ?? date('Y'));
    [$from,$to] = ym_bounds($year,$month);
    // employees
    $emps = $mysqli->query('SELECT id, full_name, base_salary FROM employees WHERE is_active=1');
    while($e=$emps->fetch_assoc()){
      $eid=(int)$e['id']; $gross=(float)$e['base_salary'];
      // sums
      $advQ = $mysqli->prepare('SELECT COALESCE(SUM(amount),0) v FROM salary_advances WHERE employee_id=? AND adv_date BETWEEN ? AND ?');
      $advQ->bind_param('iss',$eid,$from,$to); $advQ->execute(); $adv = (float)($advQ->get_result()->fetch_assoc()['v'] ?? 0);
      $dedQ = $mysqli->prepare('SELECT COALESCE(SUM(amount),0) v FROM salary_deductions WHERE employee_id=? AND ded_date BETWEEN ? AND ?');
      $dedQ->bind_param('iss',$eid,$from,$to); $dedQ->execute(); $ded = (float)($dedQ->get_result()->fetch_assoc()['v'] ?? 0);
      // incentives
      $incQ = $mysqli->prepare('SELECT COALESCE(SUM(amount),0) v FROM salary_incentives WHERE employee_id=? AND inc_date BETWEEN ? AND ?');
      $incQ->bind_param('iss',$eid,$from,$to); $incQ->execute(); $inc = (float)($incQ->get_result()->fetch_assoc()['v'] ?? 0);
      // allowances
      $allQ = $mysqli->prepare('SELECT COALESCE(SUM(amount),0) v FROM salary_allowances WHERE employee_id=? AND all_date BETWEEN ? AND ?');
      $allQ->bind_param('iss',$eid,$from,$to); $allQ->execute(); $all = (float)($allQ->get_result()->fetch_assoc()['v'] ?? 0);
      $net = $gross + $inc + $all - $adv - $ded;
      // Idempotent generate WITHOUT requiring a unique key:
      // Explicitly check existence; do UPDATE if exists, else INSERT (avoid relying on affected_rows)
      $chk = $mysqli->prepare('SELECT id FROM salary_payroll WHERE employee_id=? AND period_month=? AND period_year=? LIMIT 1');
      $chk->bind_param('iii',$eid,$month,$year);
      if(!$chk->execute()) json_response(['message'=>$chk->error],500);
      $exists = $chk->get_result()->fetch_assoc();
      $generated_on = date('Y-m-d H:i:s');
      if ($exists) {
        $upd = $mysqli->prepare('UPDATE salary_payroll SET gross_salary=?, total_incentives=?, total_allowances=?, total_advances=?, total_deductions=?, net_salary=?, generated_on=? WHERE id=?');
        $pid = (int)$exists['id'];
        $upd->bind_param('ddddddsi', $gross, $inc, $all, $adv, $ded, $net, $generated_on, $pid);
        if(!$upd->execute()) json_response(['message'=>$upd->error],500);
      } else {
        $ins = $mysqli->prepare('INSERT INTO salary_payroll (employee_id, period_month, period_year, gross_salary, total_incentives, total_allowances, total_advances, total_deductions, net_salary, generated_on) VALUES (?,?,?,?,?,?,?,?,?,?)');
        $ins->bind_param('iiidddddds', $eid, $month, $year, $gross, $inc, $all, $adv, $ded, $net, $generated_on);
        if(!$ins->execute()) json_response(['message'=>$ins->error],500);
      }
      // Recommended: add a unique index to hard-protect duplicates
      // ALTER TABLE salary_payroll ADD UNIQUE KEY uniq_emp_month (employee_id, period_month, period_year);
    }
    json_response(['message'=>'Generated']);
    break;

  case 'mark_paid':
    ensure_admin_pay(); if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message'=>'Invalid CSRF'],400);
    $id=(int)($_POST['id'] ?? 0); if(!$id) json_response(['message'=>'Missing id'],400);
    $stmt=$mysqli->prepare('UPDATE salary_payroll SET paid_on = IFNULL(paid_on, CURDATE()) WHERE id=?');
    $stmt->bind_param('i',$id);
    if(!$stmt->execute()) json_response(['message'=>$stmt->error],500);
    json_response(['message'=>'Marked paid']);
    break;

  case 'delete':
    ensure_admin_pay(); if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message'=>'Invalid CSRF'],400);
    $id=(int)($_POST['id'] ?? 0); if(!$id) json_response(['message'=>'Missing id'],400);
    // Only allow delete when unpaid
    $stmt=$mysqli->prepare('DELETE FROM salary_payroll WHERE id=? AND paid_on IS NULL');
    $stmt->bind_param('i',$id);
    if(!$stmt->execute()) json_response(['message'=>$stmt->error],500);
    if ($stmt->affected_rows===0) json_response(['message'=>'Cannot delete a paid payroll entry'], 400);
    json_response(['message'=>'Deleted']);
    break;

  default:
    json_response(['message'=>'Invalid action'],400);
}
