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

[$eOrg, $eOrgP] = orgScopeClause($db, 'e.company_id');
[$plainOrg, $plainOrgP] = orgScopeClause($db, 'company_id');

$type   = get('type') ?: 'daily_attendance';
$month  = cleanInt($_GET['month'] ?? date('n'));
$year   = cleanInt($_GET['year']  ?? date('Y'));
$fromD  = get('from') ?: date('Y-m-01');
$toD    = get('to')   ?: date('Y-m-t');
$dept   = cleanInt($_GET['dept'] ?? 0);
$empId  = cleanInt($_GET['emp']  ?? 0);
$deptFilter = $dept ? "AND e.department_id=$dept" : '';
$empFilter  = $empId ? "AND e.id=$empId" : '';

$depts = $db->fetchAll("SELECT id,name FROM departments WHERE is_active=1 ORDER BY name");
[$empListOrg, $empListOrgP] = orgScopeClause($db, 'company_id');
$employeesList = $db->fetchAll("SELECT id,CONCAT(employee_id,' - ',first_name,' ',last_name) AS label FROM employees WHERE status='active' AND $empListOrg ORDER BY first_name", $empListOrgP);

$reports = [
    'daily_attendance'    => 'Daily Attendance Report',
    'attendance_summary'  => 'Attendance Summary',
    'attendance_month'    => 'Attendance Month',
    'monthly_status'      => 'Monthly Status',
    'inout_single_col'    => 'In/Out (Single Column)',
    'log_details'         => 'Log Details',
    'quickview_excel'     => 'Quickview Excel',
    'repeat_data_format'  => 'Repeat Data Format',
    'late_machine_log'    => 'Late Machine Log',
    'attendance'          => 'Attendance',
    'unassigned_shift'    => 'Unassigned Shift',
    'shift_time'          => 'Shift Time',
    'shift_detail'        => 'Shift Detail Report',
    'mismatch'            => 'Mismatch',
    'ot_vertical'         => 'OT Vertical',
    'ot_horizontal'       => 'OT Horizontal',
    'ot_analysis'         => 'OT Analysis Report',
    'early_coming'        => 'Early Coming',
    'register'            => 'Register',
    'on_duty'             => 'On Duty Report',
    'excess_stay'         => 'Excess Stay Employee',
    'continuous_unpunch'  => 'Unpunching Report',
    'leave_report'        => 'Leave Report',
    'halfday'             => 'Half Day',
    'machinelog_export'   => 'Machine Log Export',
    'invalid_punches'     => 'Invalid Punches Export',
    'report_wizard'       => 'Report Wizard',
];
if (!isset($reports[$type])) $type = 'daily_attendance';

$cols = []; $rows = [];

switch ($type) {

    case 'daily_attendance':
        // Main day-wise attendance: Sign In / Sign Out up front, with a
        // full-text status so On Duty / Leave / Week Off / Comp Off / etc.
        // are readable at a glance instead of showing raw codes.
        $cols = ['Emp Code','Name','Department','Date','Day','Sign In','Sign Out','Status','Work Hours','Late Minutes','Remarks'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, d.name AS dept,
                    m.muster_date, DATE_FORMAT(m.muster_date,'%a') AS day_name,
                    COALESCE(TIME_FORMAT(m.in_time,'%h:%i %p'),'--') AS sign_in,
                    COALESCE(TIME_FORMAT(m.out_time,'%h:%i %p'),'--') AS sign_out,
                    CASE m.status
                      WHEN 'P'   THEN 'Present'
                      WHEN 'A'   THEN 'Absent'
                      WHEN 'H'   THEN 'Half Day'
                      WHEN 'L'   THEN 'Leave'
                      WHEN 'WO'  THEN 'Week Off'
                      WHEN 'PH'  THEN 'Holiday'
                      WHEN 'CO'  THEN 'Comp Off'
                      WHEN 'LOP' THEN 'Loss of Pay'
                      WHEN 'OD'  THEN 'On Duty'
                      ELSE m.status
                    END AS status_label,
                    m.work_hours, m.late_minutes, m.remarks
               FROM muster m JOIN employees e ON e.id=m.employee_id
          LEFT JOIN departments d ON d.id=e.department_id
              WHERE m.muster_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
              ORDER BY m.muster_date DESC, e.first_name",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;

    case 'attendance_summary':
        $cols = ['Emp Code','Name','Department','Present','Absent','Half Day','Leave','Week Off','On Duty','LOP','Late Count','OT Hours'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, d.name AS dept,
                    COALESCE(ms.present_days,0) AS present, COALESCE(ms.absent_days,0) AS absent,
                    COALESCE(ms.half_days,0) AS half_days, COALESCE(ms.leave_days,0) AS leave_days,
                    COALESCE(ms.week_off_days,0) AS week_off, COALESCE(ms.od_days,0) AS on_duty, COALESCE(ms.lop_days,0) AS lop,
                    COALESCE(ms.late_count,0) AS late_count, COALESCE(ms.ot_hours,0) AS ot_hours
               FROM employees e
          LEFT JOIN departments d ON d.id=e.department_id
          LEFT JOIN muster_summary ms ON ms.employee_id=e.id AND ms.month=? AND ms.year=?
              WHERE e.status='active' AND $eOrg $deptFilter $empFilter
              ORDER BY e.first_name",
            array_merge([$month, $year], $eOrgP)
        );
        break;

    case 'attendance_month':
    case 'monthly_status':
        $rows = $db->fetchAll(
            "SELECT e.id, e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name,
                    m.muster_date, m.status
               FROM employees e
          LEFT JOIN muster m ON m.employee_id=e.id AND MONTH(m.muster_date)=? AND YEAR(m.muster_date)=?
              WHERE e.status='active' AND $eOrg $deptFilter $empFilter
              ORDER BY e.first_name, m.muster_date",
            array_merge([$month, $year], $eOrgP)
        );
        break;

    case 'inout_single_col':
        $cols = ['Emp Code','Name','Date','Status','In - Out'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, m.muster_date, m.status,
                    CONCAT(COALESCE(m.in_time,'--'),' - ',COALESCE(m.out_time,'--')) AS in_out
               FROM muster m JOIN employees e ON e.id=m.employee_id
              WHERE m.muster_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
              ORDER BY e.first_name, m.muster_date",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;

    case 'log_details':
        $cols = ['Emp Code','Name','Date','In Time','Out Time','Source','Device'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, al.log_date, al.in_time, al.out_time, al.source, al.device_id
               FROM attendance_log al JOIN employees e ON e.id=al.employee_id
              WHERE al.log_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
              ORDER BY al.log_date DESC, e.first_name LIMIT 500",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;

    case 'quickview_excel':
        $cols = ['Emp Code','Name','Department','Present','Absent','Leave','LOP','OT Hours'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, d.name AS dept,
                    COALESCE(ms.present_days,0) AS present, COALESCE(ms.absent_days,0) AS absent,
                    COALESCE(ms.leave_days,0) AS leave_days, COALESCE(ms.lop_days,0) AS lop, COALESCE(ms.ot_hours,0) AS ot_hours
               FROM employees e
          LEFT JOIN departments d ON d.id=e.department_id
          LEFT JOIN muster_summary ms ON ms.employee_id=e.id AND ms.month=? AND ms.year=?
              WHERE e.status='active' AND $eOrg $deptFilter $empFilter ORDER BY e.first_name",
            array_merge([$month, $year], $eOrgP)
        );
        break;

    case 'repeat_data_format':
        $cols = ['Emp Code','Name','Department','Date','Status','In','Out'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, d.name AS dept,
                    m.muster_date, m.status, m.in_time, m.out_time
               FROM muster m JOIN employees e ON e.id=m.employee_id
          LEFT JOIN departments d ON d.id=e.department_id
              WHERE m.muster_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
              ORDER BY e.first_name, m.muster_date",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;

    case 'late_machine_log':
        $cols = ['Emp Code','Name','Date','In Time','Shift Start','Late Minutes'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, m.muster_date, m.in_time,
                    s.start_time, m.late_minutes
               FROM muster m JOIN employees e ON e.id=m.employee_id
          LEFT JOIN shifts s ON s.id=e.shift_id
              WHERE m.is_late=1 AND m.muster_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
              ORDER BY m.muster_date DESC",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;

    case 'attendance':
        $cols = ['Emp Code','Name','Date','Status','In Time','Out Time','Work Hours','On Duty'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, m.muster_date, m.status, m.in_time, m.out_time, m.work_hours,
                    IF(m.status='OD','Yes','No') AS on_duty
               FROM muster m JOIN employees e ON e.id=m.employee_id
              WHERE m.muster_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
              ORDER BY m.muster_date DESC, e.first_name LIMIT 500",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;

    case 'unassigned_shift':
        $cols = ['Emp Code','Name','Department','Designation'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, d.name AS dept, des.name AS designation
               FROM employees e
          LEFT JOIN departments d ON d.id=e.department_id
          LEFT JOIN designations des ON des.id=e.designation_id
              WHERE e.status='active' AND e.shift_id IS NULL AND $eOrg $deptFilter",
            $eOrgP
        );
        break;

    case 'shift_time':
        $cols = ['Shift','Code','Start','End','Work Hours','Grace (min)','Night Shift','Assigned Employees'];
        $rows = $db->fetchAll("SELECT s.name, s.code, s.start_time, s.end_time, s.work_hours, s.grace_in_minutes, IF(s.is_night_shift,'Yes','No') AS is_night_shift FROM shifts s WHERE s.is_active=1");
        foreach ($rows as &$r) {
            $r['assigned'] = (int)$db->fetchValue(
                "SELECT COUNT(*) FROM employees e WHERE e.status='active' AND $eOrg AND e.shift_id=(SELECT id FROM shifts WHERE code=?)",
                array_merge($eOrgP, [$r['code']])
            );
        }
        unset($r);
        break;

    case 'shift_detail':
        $cols = ['Emp Code','Name','Department','Shift','Start','End'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, d.name AS dept,
                    s.name AS shift_name, s.start_time, s.end_time
               FROM employees e
          LEFT JOIN departments d ON d.id=e.department_id
          LEFT JOIN shifts s ON s.id=e.shift_id
              WHERE e.status='active' AND $eOrg $deptFilter $empFilter ORDER BY e.first_name",
            $eOrgP
        );
        break;

    case 'mismatch':
        $cols = ['Emp Code','Name','Date','Muster Status','Has Log Entry?'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, m.muster_date, m.status,
                    IF(al.id IS NULL,'No','Yes') AS has_log
               FROM muster m
               JOIN employees e ON e.id=m.employee_id
          LEFT JOIN attendance_log al ON al.employee_id=m.employee_id AND al.log_date=m.muster_date
              WHERE m.muster_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
                AND ((m.status='P' AND al.id IS NULL) OR (m.status='A' AND al.id IS NOT NULL))
              ORDER BY m.muster_date DESC",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;

    case 'ot_vertical':
        $cols = ['Emp Code','Name','Date','OT Hours'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, m.muster_date, m.ot_hours
               FROM muster m JOIN employees e ON e.id=m.employee_id
              WHERE m.ot_hours > 0 AND m.muster_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
              ORDER BY e.first_name, m.muster_date",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;

    case 'ot_horizontal':
        $rows = $db->fetchAll(
            "SELECT e.id, e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name,
                    m.muster_date, m.ot_hours
               FROM employees e
          LEFT JOIN muster m ON m.employee_id=e.id AND MONTH(m.muster_date)=? AND YEAR(m.muster_date)=?
              WHERE e.status='active' AND $eOrg $deptFilter $empFilter
              ORDER BY e.first_name, m.muster_date",
            array_merge([$month, $year], $eOrgP)
        );
        break;

    case 'ot_analysis':
        $cols = ['Department','Employees with OT','Total OT Hours','Avg OT/Employee'];
        $rows = $db->fetchAll(
            "SELECT d.name AS dept, COUNT(DISTINCT m.employee_id) AS emp_count, SUM(m.ot_hours) AS total_ot,
                    ROUND(SUM(m.ot_hours)/NULLIF(COUNT(DISTINCT m.employee_id),0),2) AS avg_ot
               FROM muster m
               JOIN employees e ON e.id=m.employee_id
          LEFT JOIN departments d ON d.id=e.department_id
              WHERE m.ot_hours>0 AND MONTH(m.muster_date)=? AND YEAR(m.muster_date)=? AND $eOrg
              GROUP BY d.name ORDER BY total_ot DESC",
            array_merge([$month, $year], $eOrgP)
        );
        break;

    case 'early_coming':
        $cols = ['Emp Code','Name','Date','In Time','Shift Start','Minutes Early'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, m.muster_date, m.in_time, s.start_time,
                    TIMESTAMPDIFF(MINUTE, m.muster_date + INTERVAL 0 SECOND + m.in_time, m.muster_date + INTERVAL 0 SECOND + s.start_time) AS mins_early
               FROM muster m
               JOIN employees e ON e.id=m.employee_id
          LEFT JOIN shifts s ON s.id=e.shift_id
              WHERE m.in_time IS NOT NULL AND s.start_time IS NOT NULL AND m.in_time < s.start_time
                AND m.muster_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
              ORDER BY mins_early DESC",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;

    case 'register':
        $cols = ['Emp Code','Name','Department','Designation','Date','Status','In','Out','Work Hrs'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, d.name AS dept, des.name AS designation,
                    m.muster_date, m.status, m.in_time, m.out_time, m.work_hours
               FROM muster m
               JOIN employees e ON e.id=m.employee_id
          LEFT JOIN departments d ON d.id=e.department_id
          LEFT JOIN designations des ON des.id=e.designation_id
              WHERE m.muster_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
              ORDER BY e.first_name, m.muster_date",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;

    case 'on_duty':
        $cols = ['Emp Code','Name','Department','Date','In Time','Out Time','Work Hours','Remarks'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, d.name AS dept,
                    m.muster_date, m.in_time, m.out_time, m.work_hours, m.remarks
               FROM muster m JOIN employees e ON e.id=m.employee_id
          LEFT JOIN departments d ON d.id=e.department_id
              WHERE m.status='OD' AND m.muster_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
              ORDER BY m.muster_date DESC, e.first_name",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;

    case 'excess_stay':
        $cols = ['Emp Code','Name','Date','Work Hours','Shift Hours','Excess Hours'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, m.muster_date, m.work_hours, s.work_hours AS shift_hours,
                    ROUND(m.work_hours - s.work_hours,2) AS excess
               FROM muster m
               JOIN employees e ON e.id=m.employee_id
          LEFT JOIN shifts s ON s.id=e.shift_id
              WHERE s.work_hours IS NOT NULL AND m.work_hours > (s.work_hours + 1)
                AND m.muster_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
              ORDER BY excess DESC",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;

    case 'continuous_unpunch':
        $cols = ['Emp Code','Name','Department','Date','Status','In Time','Out Time','Issue'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, d.name AS dept,
                    m.muster_date, m.status, m.in_time, m.out_time,
                    IF(m.in_time IS NULL AND m.out_time IS NULL,'Missing In & Out',
                       IF(m.in_time IS NULL,'Missing In Time','Missing Out Time')) AS issue
               FROM muster m JOIN employees e ON e.id=m.employee_id
          LEFT JOIN departments d ON d.id=e.department_id
              WHERE m.status='P' AND (m.in_time IS NULL OR m.out_time IS NULL)
                AND m.muster_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
              ORDER BY e.first_name, m.muster_date DESC",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;

    case 'halfday':
        $cols = ['Emp Code','Name','Date','In','Out','Work Hours'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, m.muster_date, m.in_time, m.out_time, m.work_hours
               FROM muster m JOIN employees e ON e.id=m.employee_id
              WHERE m.status='H' AND m.muster_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
              ORDER BY m.muster_date DESC",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;

    case 'machinelog_export':
        $cols = ['Emp Code','Name','Date','In Time','Out Time','Source','Device ID'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, al.log_date, al.in_time, al.out_time, al.source, al.device_id
               FROM attendance_log al JOIN employees e ON e.id=al.employee_id
              WHERE al.log_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
              ORDER BY al.log_date, e.first_name",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;

    case 'invalid_punches':
        $cols = ['Emp Code','Name','Date','In Time','Out Time','Issue'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, al.log_date, al.in_time, al.out_time,
                    IF(al.in_time IS NULL,'Missing check-in',IF(al.out_time IS NULL,'Missing check-out','Out before In')) AS issue
               FROM attendance_log al JOIN employees e ON e.id=al.employee_id
              WHERE (al.in_time IS NULL OR al.out_time IS NULL OR al.out_time < al.in_time)
                AND al.log_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
              ORDER BY al.log_date DESC",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;

    case 'leave_report':
        $cols = ['Emp Code','Name','Department','Leave Type','From','To','Days','Half Day','Status','Reason','Applied On','Approved By'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, d.name AS dept,
                    lt.name AS leave_type, la.from_date, la.to_date, la.days,
                    IF(la.is_half_day=1,'Yes','No') AS is_half_day, la.status, la.reason,
                    la.created_at, CONCAT(ap.first_name,' ',ap.last_name) AS approved_by
               FROM leave_applications la
               JOIN employees e ON e.id=la.employee_id
          LEFT JOIN departments d ON d.id=e.department_id
          LEFT JOIN leave_types lt ON lt.id=la.leave_type_id
          LEFT JOIN employees ap ON ap.id=la.approved_by
              WHERE ((la.from_date BETWEEN ? AND ?) OR (la.to_date BETWEEN ? AND ?) OR (la.from_date <= ? AND la.to_date >= ?))
                AND $eOrg $deptFilter $empFilter
              ORDER BY la.from_date DESC, e.first_name",
            array_merge([$fromD, $toD, $fromD, $toD, $fromD, $toD], $eOrgP)
        );
        break;

    case 'report_wizard':
        $cols = ['Emp Code','Name','Department','Date','Status','In','Out'];
        $rows = $db->fetchAll(
            "SELECT e.employee_id, CONCAT(e.first_name,' ',e.last_name) AS name, d.name AS dept, m.muster_date, m.status, m.in_time, m.out_time
               FROM muster m JOIN employees e ON e.id=m.employee_id
          LEFT JOIN departments d ON d.id=e.department_id
              WHERE m.muster_date BETWEEN ? AND ? AND $eOrg $deptFilter $empFilter
              ORDER BY e.first_name, m.muster_date",
            array_merge([$fromD, $toD], $eOrgP)
        );
        break;
}

// Grid (calendar-style) reports build a per-employee/per-day matrix.
// Computed once here so both the CSV export and the on-screen table below
// can reuse it without duplicating the loop.
$daysInMonth = (int)date('t', strtotime("$year-$month-01"));
$grid = [];
if (in_array($type, ['attendance_month','monthly_status'])) {
    foreach ($rows as $r) {
        $grid[$r['id']]['name'] = $r['employee_id'].' - '.$r['name'];
        if ($r['muster_date']) $grid[$r['id']]['days'][$r['muster_date']] = $r['status'];
    }
} elseif ($type === 'ot_horizontal') {
    foreach ($rows as $r) {
        $grid[$r['id']]['name'] = $r['employee_id'].' - '.$r['name'];
        if ($r['muster_date']) $grid[$r['id']]['days'][$r['muster_date']] = $r['ot_hours'];
    }
}

// ── CSV download ────────────────────────────────────────────────
if (get('format') === 'csv') {
    $filename = 'monthly_summary_'.$type.'_'.date('Ymd_His').'.csv';
    header('Content-Type: text/csv; charset=UTF-8');
    header('Content-Disposition: attachment; filename="'.$filename.'"');
    header('Pragma: no-cache'); header('Expires: 0');
    $out = fopen('php://output', 'w');
    fputs($out, "\xEF\xBB\xBF"); // UTF-8 BOM so Excel renders it correctly

    if (in_array($type, ['attendance_month','monthly_status'])) {
        $header = ['Employee'];
        for ($d=1;$d<=$daysInMonth;$d++) $header[] = $d;
        fputcsv($out, $header);
        foreach ($grid as $g) {
            $line = [$g['name']];
            for ($d=1;$d<=$daysInMonth;$d++) { $dt = sprintf('%04d-%02d-%02d',$year,$month,$d); $line[] = $g['days'][$dt] ?? '-'; }
            fputcsv($out, $line);
        }
    } elseif ($type === 'ot_horizontal') {
        $header = ['Employee'];
        for ($d=1;$d<=$daysInMonth;$d++) $header[] = $d;
        $header[] = 'Total';
        fputcsv($out, $header);
        foreach ($grid as $g) {
            $tot = 0; $line = [$g['name']];
            for ($d=1;$d<=$daysInMonth;$d++) { $dt = sprintf('%04d-%02d-%02d',$year,$month,$d); $v = (float)($g['days'][$dt] ?? 0); $tot += $v; $line[] = $v > 0 ? $v : '-'; }
            $line[] = $tot;
            fputcsv($out, $line);
        }
    } else {
        fputcsv($out, $cols);
        foreach ($rows as $r) {
            $line = [];
            foreach ($r as $k => $v) { if (is_numeric($k)) continue; $line[] = $v ?? ''; }
            fputcsv($out, $line);
        }
    }
    fclose($out);
    exit;
}

include __DIR__ . '/../../includes/header.php';
?>
<div class="row g-3">
  <div class="col-md-3">
    <div class="pc-card p-2" style="max-height:650px;overflow-y:auto">
      <div class="pc-card-title">Monthly Summary Reports</div>
      <div class="list-group list-group-flush">
        <?php foreach ($reports as $key => $label): ?>
        <a href="?type=<?= $key ?>&month=<?=$month?>&year=<?=$year?>&from=<?=$fromD?>&to=<?=$toD?>&dept=<?=$dept?>&emp=<?=$empId?>"
           class="list-group-item list-group-item-action small <?= $type===$key?'active':'' ?>"><?= clean($label) ?></a>
        <?php endforeach; ?>
      </div>
    </div>
  </div>

  <div class="col-md-9">
    <div class="pc-card mb-3">
      <form method="GET" class="d-flex gap-2 flex-wrap align-items-end">
        <input type="hidden" name="type" value="<?= $type ?>">
        <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?>" <?=$month==$m?'selected':''?>><?=monthName($m)?></option><?php endfor; ?>
          </select></div>
        <div><label class="pc-label">Year</label><input type="number" name="year" value="<?=$year?>" class="form-control form-control-sm" style="width:85px"></div>
        <div><label class="pc-label">From</label><input type="date" name="from" value="<?=$fromD?>" class="form-control form-control-sm"></div>
        <div><label class="pc-label">To</label><input type="date" name="to" value="<?=$toD?>" class="form-control form-control-sm"></div>
        <div><label class="pc-label">Department</label>
          <select name="dept" class="form-select form-select-sm">
            <option value="">All (General)</option>
            <?php foreach($depts as $d): ?><option value="<?=$d['id']?>" <?=$dept==$d['id']?'selected':''?>><?=clean($d['name'])?></option><?php endforeach; ?>
          </select></div>
        <div><label class="pc-label">Emp Code</label>
          <select name="emp" class="form-select form-select-sm" style="width:220px">
            <option value="">All</option>
            <?php foreach($employeesList as $e): ?><option value="<?=$e['id']?>" <?=$empId==$e['id']?'selected':''?>><?=clean($e['label'])?></option><?php endforeach; ?>
          </select></div>
        <button class="btn btn-pc btn-sm">Apply</button>
      </form>
    </div>

    <div class="pc-card">
      <div class="pc-card-title d-flex justify-content-between align-items-center">
        <span><?= clean($reports[$type]) ?></span>
        <span>
          <a href="?<?= http_build_query(array_merge($_GET, ['type'=>$type,'month'=>$month,'year'=>$year,'from'=>$fromD,'to'=>$toD,'dept'=>$dept,'emp'=>$empId,'format'=>'csv'])) ?>" class="small me-3"><i class="ti ti-download me-1"></i>Download CSV</a>
          <a href="#" onclick="window.print();return false;" class="small"><i class="ti ti-printer me-1"></i>Print</a>
        </span>
      </div>

      <?php if (in_array($type, ['attendance_month','monthly_status'])): ?>
        <div class="pc-table-wrap">
          <table class="pc-table" style="font-size:11px">
            <thead><tr><th>Employee</th><?php for($d=1;$d<=$daysInMonth;$d++): ?><th><?=$d?></th><?php endfor; ?></tr></thead>
            <tbody>
            <?php foreach ($grid as $g): ?>
              <tr><td class="fw-semibold"><?=clean($g['name'])?></td>
              <?php for($d=1;$d<=$daysInMonth;$d++): $dt = sprintf('%04d-%02d-%02d',$year,$month,$d); ?>
                <td class="text-center"><?=clean($g['days'][$dt] ?? '-')?></td>
              <?php endfor; ?></tr>
            <?php endforeach; ?>
            <?php if (!$grid): ?><tr><td colspan="32" class="text-center text-muted py-4">No records</td></tr><?php endif; ?>
            </tbody>
          </table>
        </div>

      <?php elseif ($type === 'ot_horizontal'): ?>
        <div class="pc-table-wrap">
          <table class="pc-table" style="font-size:11px">
            <thead><tr><th>Employee</th><?php for($d=1;$d<=$daysInMonth;$d++): ?><th><?=$d?></th><?php endfor; ?><th>Total</th></tr></thead>
            <tbody>
            <?php foreach ($grid as $g): $tot=0; ?>
              <tr><td class="fw-semibold"><?=clean($g['name'])?></td>
              <?php for($d=1;$d<=$daysInMonth;$d++): $dt = sprintf('%04d-%02d-%02d',$year,$month,$d); $v=(float)($g['days'][$dt] ?? 0); $tot+=$v; ?>
                <td class="text-center"><?= $v>0?$v:'-' ?></td>
              <?php endfor; ?><td class="fw-bold"><?=$tot?></td></tr>
            <?php endforeach; ?>
            <?php if (!$grid): ?><tr><td colspan="32" class="text-center text-muted py-4">No records</td></tr><?php endif; ?>
            </tbody>
          </table>
        </div>

      <?php else: ?>
        <div class="pc-table-wrap">
          <table class="pc-table">
            <thead><tr><?php foreach ($cols as $c): ?><th><?= clean($c) ?></th><?php endforeach; ?></tr></thead>
            <tbody>
            <?php foreach ($rows as $r): ?>
              <tr><?php foreach ($r as $k => $v): if (is_numeric($k)) continue; ?><td><?= clean(is_null($v) ? '—' : $v) ?></td><?php endforeach; ?></tr>
            <?php endforeach; ?>
            <?php if (!$rows): ?><tr><td colspan="10" class="text-center text-muted py-4">No records found</td></tr><?php endif; ?>
            </tbody>
          </table>
        </div>
      <?php endif; ?>
    </div>
  </div>
</div>
<?php include __DIR__ . '/../../includes/footer.php'; ?>