<?php
require_once __DIR__ . '/../../config/config.php';
require_once __DIR__ . '/../../includes/functions.php';
startSession(); requireLogin(); requireRole('superadmin','admin','hr','management');
$db   = Database::getInstance();
$page = 'Salary Calculation';

$month = cleanInt($_GET['month'] ?? date('n'));
$year  = cleanInt($_GET['year']  ?? date('Y'));
$dept  = cleanInt($_GET['dept']  ?? 0);

// FIX (07 Jul 2026): payroll_runs used to have UNIQUE KEY (month,year)
// with no company scoping at all — meaning only ONE organization in the
// whole database could have a payroll run for a given month; a second
// org processing the same month would either collide or silently see/
// overwrite the first org's run. Added company_id (see
// migration_payroll_runs_company.sql) and a company selector here since
// an org can have multiple companies, each running its own payroll.
$orgCompanies = orgCompanyIds($db);
$rawCompany   = $_GET['company'] ?? post('company_id') ?? 0;
$companyId    = cleanInt($rawCompany) ?: ($orgCompanies[0] ?? 0);
if (!in_array($companyId, $orgCompanies)) { $companyId = $orgCompanies[0] ?? 0; }

// ── Payroll Engine ──────────────────────────────────────────
function calculatePayroll(int $empId, int $month, int $year, Database $db): array {
    // Muster summary
    $ms = $db->fetchOne(
        "SELECT * FROM muster_summary WHERE employee_id=? AND month=? AND year=?",
        [$empId, $month, $year]
    );
    $workingDays = $ms['present_days'] ?? 26;
    $lopDays     = $ms['lop_days']     ?? 0;
    $presentDays = $workingDays - $lopDays;

    // Salary components
    $salRow = $db->fetchOne("SELECT * FROM employee_salary WHERE employee_id=?", [$empId]);
    $gross  = $salRow['gross_monthly'] ?? 0;

    // Proportionate calculation for LOP
    $perDay     = $gross > 0 ? $gross / $workingDays : 0;
    $lopDeduct  = $perDay * $lopDays;
    $effectiveGross = $gross - $lopDeduct;

    // Salary heads
    $comp = $db->fetchAll(
        "SELECT sh.code, esc.amount, esc.percentage FROM employee_salary_components esc
          JOIN salary_heads sh ON sh.id = esc.salary_head_id
         WHERE esc.employee_id=?", [$empId]
    );
    $compMap = array_column($comp, null, 'code');

    $basic   = $compMap['BASIC']['amount']  ?? ($effectiveGross * 0.40);
    $hra     = $compMap['HRA']['amount']    ?? ($basic * 0.50);
    $da      = $compMap['DA']['amount']     ?? 0;
    $conv    = $compMap['CONV']['amount']   ?? 1600;
    $medical = $compMap['MED']['amount']    ?? 1250;
    $special = $effectiveGross - $basic - $hra - $da - $conv - $medical;
    $special = max(0, $special);

    // PF
    $emp  = $db->fetchOne("SELECT * FROM employees WHERE id=?", [$empId]);
    $pfSetup = $db->fetchOne("SELECT * FROM pf_setup WHERE is_active=1 LIMIT 1");
    $pf_employee = 0; $pf_employer = 0;
    if ($emp['pf_applicable']) {
        $pfWage = min($basic + $da, $pfSetup['pf_wage_ceiling'] ?? 15000);
        $pf_employee = round($pfWage * ($pfSetup['pf_employee_rate'] ?? 12) / 100, 2);
        $pf_employer = round($pfWage * ($pfSetup['pf_employer_rate'] ?? 12) / 100, 2);
    }

    // ESI
    $esi_employee = 0; $esi_employer = 0;
    $esiSetup = $db->fetchOne("SELECT * FROM esi_setup WHERE is_active=1 LIMIT 1");
    if ($emp['esi_applicable'] && $effectiveGross <= ($esiSetup['wage_ceiling'] ?? 21000)) {
        $esi_employee = round($effectiveGross * ($esiSetup['employee_rate'] ?? 0.75) / 100, 2);
        $esi_employer = round($effectiveGross * ($esiSetup['employer_rate'] ?? 3.25) / 100, 2);
    }

    // Professional Tax
    $pt = 0;
    if ($emp['pt_applicable']) {
        $ptSlabs = $db->fetchAll("SELECT * FROM pt_slabs WHERE is_active=1 ORDER BY income_from");
        foreach ($ptSlabs as $slab) {
            if ($effectiveGross >= $slab['income_from'] && $effectiveGross <= $slab['income_to']) {
                $pt = $slab['monthly_pt']; break;
            }
        }
    }

    // Advance recovery
    $advRecovery = $db->fetchValue(
        "SELECT COALESCE(SUM(total_amount),0) FROM advance_repayments ar
          JOIN advance_applications aa ON aa.id = ar.advance_id
         WHERE aa.employee_id=? AND ar.month=? AND ar.year=? AND ar.status='pending'",
        [$empId, $month, $year]
    ) ?? 0;

    // TDS (monthly)
    $tdsRow = $db->fetchOne(
        "SELECT tds_this_month FROM tds_calculations WHERE employee_id=? AND month=? AND year=?",
        [$empId, $month, $year]
    );
    $tds = $tdsRow['tds_this_month'] ?? 0;

    $totalEarnings   = $basic + $hra + $da + $conv + $medical + $special;
    $totalDeductions = $pf_employee + $esi_employee + $pt + $tds + $advRecovery;
    $netSalary       = $totalEarnings - $totalDeductions;

    return [
        'present_days'    => $presentDays,
        'lop_days'        => $lopDays,
        'basic'           => round($basic, 2),
        'hra'             => round($hra, 2),
        'da'              => round($da, 2),
        'conveyance'      => round($conv, 2),
        'medical'         => round($medical, 2),
        'special_allowance'=> round($special, 2),
        'gross_salary'    => round($totalEarnings, 2),
        'pf_employee'     => $pf_employee,
        'pf_employer'     => $pf_employer,
        'esi_employee'    => $esi_employee,
        'esi_employer'    => $esi_employer,
        'professional_tax'=> $pt,
        'income_tax'      => $tds,
        'advance_recovery'=> $advRecovery,
        'total_deductions'=> round($totalDeductions, 2),
        'net_salary'      => round($netSalary, 2),
    ];
}

// POST: Process payroll
$message = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && post('action') === 'process') {
    verifyCsrf();
    $processMonth = postInt('month');
    $processYear  = postInt('year');

    $existing = $db->fetchOne("SELECT id,status FROM payroll_runs WHERE company_id=? AND month=? AND year=?", [$companyId,$processMonth,$processYear]);
    if ($existing && in_array($existing['status'],['posted','disbursed'])) {
        setFlash('error','Payroll already posted. Cannot reprocess.');
    } else {
        $db->beginTransaction();
        try {
            $runId = $existing ? $existing['id'] :
                $db->insertRow('payroll_runs', ['company_id'=>$companyId,'month'=>$processMonth,'year'=>$processYear,'status'=>'draft','run_date'=>date('Y-m-d')]);

            // Clear previous draft
            $db->execute("DELETE FROM payroll_details WHERE payroll_run_id=?", [$runId]);

            $where  = 'e.status = "active" AND e.company_id=?';
            $params = [$companyId];
            if ($dept) { $where .= ' AND e.department_id=?'; $params[] = $dept; }

            $employees = $db->fetchAll("SELECT e.id FROM employees e WHERE $where ORDER BY e.employee_id", $params);

            $totGross = $totDed = $totNet = 0;
            foreach ($employees as $e) {
                $pay = calculatePayroll($e['id'], $processMonth, $processYear, $db);
                $pay['payroll_run_id'] = $runId;
                $pay['employee_id']    = $e['id'];
                $pay['month']          = $processMonth;
                $pay['year']           = $processYear;
                $db->insertRow('payroll_details', $pay);
                $totGross += $pay['gross_salary'];
                $totDed   += $pay['total_deductions'];
                $totNet   += $pay['net_salary'];
            }

            $db->execute("UPDATE payroll_runs SET status='processed',total_employees=?,total_gross=?,total_deductions=?,total_net=?,processed_by=? WHERE id=?",
                [count($employees), $totGross, $totDed, $totNet, currentUser()['id'], $runId]);

            $db->commit();
            setFlash('success', 'Payroll processed for ' . count($employees) . ' employees. Total Net: ' . money($totNet));
            $month = $processMonth; $year = $processYear;
        } catch (Exception $ex) {
            $db->rollback();
            setFlash('error','Payroll processing failed: ' . $ex->getMessage());
        }
    }
}

// Fetch run & details
$run = $db->fetchOne("SELECT * FROM payroll_runs WHERE company_id=? AND month=? AND year=?", [$companyId,$month,$year]);
$details = [];
if ($run) {
    $deptFilter = $dept ? " AND e.department_id=$dept" : '';
    $details = $db->fetchAll(
        "SELECT pd.*, e.employee_id AS emp_code, e.first_name, e.last_name, d.name AS dept, des.name AS desig
           FROM payroll_details pd
           JOIN employees e ON e.id = pd.employee_id
      LEFT JOIN departments d ON d.id = e.department_id
      LEFT JOIN designations des ON des.id = e.designation_id
          WHERE pd.payroll_run_id=? $deptFilter ORDER BY e.employee_id",
        [$run['id']]
    );
}
$departments = $db->fetchAll("SELECT id,name FROM departments WHERE is_active=1 ORDER BY name");
$companyRows = $orgCompanies ? $db->fetchAll("SELECT id,name FROM companies WHERE id IN (".implode(',',array_fill(0,count($orgCompanies),'?')).")", $orgCompanies) : [];

$headerActions = '
<form method="POST" class="d-inline" onsubmit="return confirm(\"Process payroll for '.monthName($month).' '.$year.'? This will overwrite draft.\")">
  '.csrfField().'
  <input type="hidden" name="action" value="process">
  <input type="hidden" name="month" value="'.$month.'">
  <input type="hidden" name="year"  value="'.$year.'">
  <input type="hidden" name="dept"  value="'.$dept.'">
  <input type="hidden" name="company_id" value="'.$companyId.'">
  <button type="submit" class="btn btn-pc btn-sm"><i class="ti ti-calculator me-1"></i>Process Payroll</button>
</form>';
if ($run && $run['status']==='processed') {
    $headerActions .= '
    <form method="POST" class="d-inline ms-1">
      '.csrfField().'
      <input type="hidden" name="action" value="post">
      <input type="hidden" name="run_id" value="'.$run['id'].'">
      <button type="submit" class="btn btn-success btn-sm"><i class="ti ti-check me-1"></i>Post Salary</button>
    </form>';
}
$headerActions .= '<a href="payslip_bulk.php?month='.$month.'&year='.$year.'" class="btn btn-sm btn-outline-secondary ms-1"><i class="ti ti-download me-1"></i>Download Payslips</a>';

include __DIR__ . '/../../includes/header.php';
?>

<!-- Filters -->
<div class="pc-card mb-3">
  <form method="GET" class="pc-filters">
    <?php if (count($companyRows) > 1): ?>
    <div>
      <label class="pc-label">Company</label>
      <select name="company" class="form-select form-select-sm">
        <?php foreach ($companyRows as $c): ?>
        <option value="<?= $c['id'] ?>" <?= $companyId==$c['id']?'selected':'' ?>><?= clean($c['name']) ?></option>
        <?php endforeach; ?>
      </select>
    </div>
    <?php else: ?>
    <input type="hidden" name="company" value="<?= $companyId ?>">
    <?php endif; ?>
    <div>
      <label class="pc-label">Month</label>
      <select name="month" class="form-select form-select-sm">
        <?php for ($m=1;$m<=12;$m++): ?>
        <option value="<?= $m ?>" <?= $m===$month?'selected':'' ?>><?= monthName($m) ?></option>
        <?php endfor; ?>
      </select>
    </div>
    <div>
      <label class="pc-label">Year</label>
      <select name="year" class="form-select form-select-sm">
        <?php for ($y=date('Y')-2;$y<=date('Y')+1;$y++): ?>
        <option value="<?= $y ?>" <?= $y===$year?'selected':'' ?>><?= $y ?></option>
        <?php endfor; ?>
      </select>
    </div>
    <div>
      <label class="pc-label">Department</label>
      <select name="dept" class="form-select form-select-sm">
        <option value="">All Departments</option>
        <?php foreach ($departments as $d): ?>
        <option value="<?= $d['id'] ?>" <?= $dept==$d['id']?'selected':'' ?>><?= clean($d['name']) ?></option>
        <?php endforeach; ?>
      </select>
    </div>
    <div style="margin-top:auto"><button type="submit" class="btn btn-pc btn-sm"><i class="ti ti-search me-1"></i>Fetch</button></div>
  </form>
</div>

<!-- Stats -->
<?php if ($run): ?>
<div class="row g-3 mb-3">
  <?php $rstats = [
    ['label'=>'Employees Processed','val'=>number_format($run['total_employees']),'cls'=>'brand'],
    ['label'=>'Total Gross','val'=>money($run['total_gross']),'cls'=>'green'],
    ['label'=>'Total Deductions','val'=>money($run['total_deductions']),'cls'=>'red'],
    ['label'=>'Net Payable','val'=>money($run['total_net']),'cls'=>'blue'],
  ];
  foreach ($rstats as $s): ?>
  <div class="col-6 col-md-3">
    <div class="pc-stat text-center">
      <div class="pc-stat-val" style="color:var(--pc-brand)"><?= $s['val'] ?></div>
      <div class="pc-stat-label"><?= $s['label'] ?></div>
    </div>
  </div>
  <?php endforeach; ?>
</div>
<div class="alert alert-<?= ['draft'=>'secondary','processed'=>'warning','posted'=>'success','disbursed'=>'info'][$run['status']] ?> py-2 small">
  <strong>Status:</strong> <?= ucfirst($run['status']) ?> | 
  <strong>Run Date:</strong> <?= fmtDate($run['run_date']) ?> |
  <strong>Period:</strong> <?= monthName($month) ?> <?= $year ?>
</div>
<?php endif; ?>

<!-- Payroll Details Table -->
<div class="pc-card">
  <div class="d-flex justify-content-between align-items-center mb-3">
    <div class="fw-semibold">Payroll Details – <?= monthName($month) ?> <?= $year ?></div>
    <?php if ($details): ?>
    <a href="export_payroll.php?month=<?= $month ?>&year=<?= $year ?>" class="btn btn-sm btn-outline-secondary">
      <i class="ti ti-download me-1"></i>Export Excel
    </a>
    <?php endif; ?>
  </div>
  <?php if ($details): ?>
  <div class="pc-table-wrap">
    <table class="pc-table" style="font-size:11px">
      <thead>
        <tr>
          <th>Employee</th><th>Dept</th><th>Days</th><th>LOP</th>
          <th>Basic</th><th>HRA</th><th>Allowances</th>
          <th>Gross</th><th>PF</th><th>ESI</th><th>PT</th><th>TDS</th><th>Adv.Rec</th>
          <th>Deductions</th><th>Net Pay</th><th>Action</th>
        </tr>
      </thead>
      <tbody>
      <?php
      $totalRow = array_fill_keys(['gross_salary','pf_employee','esi_employee','professional_tax','income_tax','advance_recovery','total_deductions','net_salary'], 0);
      foreach ($details as $d):
        foreach ($totalRow as $k=>$_) $totalRow[$k] += $d[$k];
        $allowances = $d['conveyance'] + $d['medical'] + $d['special_allowance'] + $d['da'];
      ?>
      <tr>
        <td>
          <div class="fw-semibold"><?= clean($d['first_name'].' '.$d['last_name']) ?></div>
          <div style="color:var(--pc-text2)"><?= clean($d['emp_code']) ?></div>
        </td>
        <td><?= clean($d['dept']??'') ?></td>
        <td><?= $d['present_days'] ?></td>
        <td style="color:var(--pc-danger)"><?= $d['lop_days'] ?></td>
        <td><?= money($d['basic']) ?></td>
        <td><?= money($d['hra']) ?></td>
        <td><?= money($allowances) ?></td>
        <td class="fw-semibold"><?= money($d['gross_salary']) ?></td>
        <td><?= money($d['pf_employee']) ?></td>
        <td><?= money($d['esi_employee']) ?></td>
        <td><?= money($d['professional_tax']) ?></td>
        <td><?= money($d['income_tax']) ?></td>
        <td><?= money($d['advance_recovery']) ?></td>
        <td style="color:var(--pc-danger)"><?= money($d['total_deductions']) ?></td>
        <td class="fw-bold" style="color:var(--pc-success)"><?= money($d['net_salary']) ?></td>
        <td><a href="../employees/payslip.php?emp=<?= $d['employee_id'] ?>&month=<?= $month ?>&year=<?= $year ?>" class="btn btn-sm btn-outline-primary" target="_blank">
          <i class="ti ti-receipt"></i>
        </a></td>
      </tr>
      <?php endforeach; ?>
      </tbody>
      <tfoot>
        <tr class="fw-bold" style="background:var(--pc-brand-light)">
          <td colspan="4">TOTAL</td>
          <td colspan="3"></td>
          <td><?= money($totalRow['gross_salary']) ?></td>
          <td><?= money($totalRow['pf_employee']) ?></td>
          <td><?= money($totalRow['esi_employee']) ?></td>
          <td><?= money($totalRow['professional_tax']) ?></td>
          <td><?= money($totalRow['income_tax']) ?></td>
          <td><?= money($totalRow['advance_recovery']) ?></td>
          <td style="color:var(--pc-danger)"><?= money($totalRow['total_deductions']) ?></td>
          <td style="color:var(--pc-success)"><?= money($totalRow['net_salary']) ?></td>
          <td></td>
        </tr>
      </tfoot>
    </table>
  </div>
  <?php else: ?>
  <div class="text-center py-5 text-muted">
    <i class="ti ti-calculator d-block fs-1 mb-2"></i>
    <div>No payroll data found. Click <strong>Process Payroll</strong> to calculate.</div>
  </div>
  <?php endif; ?>
</div>
<?php include __DIR__ . '/../../includes/footer.php'; ?>