<?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');
$db = db();
$action = $_GET['action'] ?? $_POST['action'] ?? 'list_days';

function ensure_attendance_schema(mysqli $db){
  // employees_attendance
  $exists = $db->query("SHOW TABLES LIKE 'employees_attendance'");
  if (!$exists || $exists->num_rows === 0) {
    $sql = "CREATE TABLE employees_attendance (
      id INT AUTO_INCREMENT PRIMARY KEY,
      employee_id INT NOT NULL,
      att_date DATE NOT NULL,
      status ENUM('present','absent','leave','holiday','off','work_from_home','half_day','short_leave') NOT NULL DEFAULT 'present',
      check_in TIME NULL,
      check_out TIME NULL,
      hours_worked DECIMAL(5,2) NULL,
      late_minutes SMALLINT NULL,
      ot_minutes SMALLINT NULL,
      notes VARCHAR(255) NULL,
      branch_id INT NULL,
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
      UNIQUE KEY uniq_emp_date (employee_id, att_date),
      INDEX idx_date (att_date),
      INDEX idx_emp (employee_id),
      INDEX idx_branch (branch_id),
      CONSTRAINT fk_att_emp FOREIGN KEY (employee_id) REFERENCES employees(id) ON DELETE CASCADE,
      CONSTRAINT fk_att_branch FOREIGN KEY (branch_id) REFERENCES branches(id) ON DELETE SET NULL
    ) ENGINE=InnoDB";
    @$db->query($sql);
  } else {
    // add missing columns if needed
    $cols = [];
    $res = $db->query("SHOW COLUMNS FROM employees_attendance");
    if ($res) while($r=$res->fetch_assoc()){ $cols[$r['Field']]=true; }
    if (empty($cols['late_minutes'])) {@$db->query("ALTER TABLE employees_attendance ADD COLUMN late_minutes SMALLINT NULL AFTER hours_worked");}
    if (empty($cols['ot_minutes'])) {@$db->query("ALTER TABLE employees_attendance ADD COLUMN ot_minutes SMALLINT NULL AFTER late_minutes");}
    if (empty($cols['branch_id'])) {@$db->query("ALTER TABLE employees_attendance ADD COLUMN branch_id INT NULL AFTER notes");}
  }
}

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

function calc_hours($in, $out){
  if (!$in || !$out) return null;
  $inTs = strtotime($in); $outTs = strtotime($out);
  if ($inTs===false || $outTs===false || $outTs <= $inTs) return null;
  $mins = (int)round(($outTs - $inTs)/60);
  // Round to nearest 15 mins
  $mins = (int)(round($mins/15)*15);
  return round($mins/60, 2);
}

ensure_attendance_schema($db);

switch ($action) {
  case 'list_days': {
    $month = (int)($_GET['month'] ?? date('n'));
    $year = (int)($_GET['year'] ?? date('Y'));
    $branch_id = isset($_GET['branch_id']) && $_GET['branch_id']!=='' ? (int)$_GET['branch_id'] : 0;
    $employee_id = isset($_GET['employee_id']) && $_GET['employee_id']!=='' ? (int)$_GET['employee_id'] : 0;
    $start = sprintf('%04d-%02d-01',$year,$month);
    $end = date('Y-m-t', strtotime($start));
    $where = ' WHERE e.is_active=1';
    $types = ''; $params = [];
    if ($branch_id) { $where .= ' AND e.branch_id=?'; $types.='i'; $params[]=$branch_id; }
    if ($employee_id) { $where .= ' AND e.id=?'; $types.='i'; $params[]=$employee_id; }
    $sqlEmp = 'SELECT e.id, e.emp_code, e.full_name, e.branch_id FROM employees e'. $where . ' ORDER BY e.emp_code';
    if ($types){ $stmt=$db->prepare($sqlEmp); $stmt->bind_param($types, ...$params); $stmt->execute(); $emps=$stmt->get_result(); }
    else { $emps = $db->query($sqlEmp); }
    $empRows = []; while($r=$emps->fetch_assoc()){ $empRows[]=$r; }
    // fetch attendance records in month for those employees
    $ids = array_column($empRows,'id');
    $attMap = [];
    if (!empty($ids)){
      $in = implode(',', array_map('intval',$ids));
      $q = $db->query("SELECT employee_id, att_date, status, check_in, check_out, hours_worked, late_minutes, ot_minutes, notes FROM employees_attendance WHERE employee_id IN ($in) AND att_date BETWEEN '".$db->real_escape_string($start)."' AND '".$db->real_escape_string($end)."'");
      while($a=$q->fetch_assoc()){
        $attMap[$a['employee_id']][$a['att_date']] = $a;
      }
    }
    json_response(['employees'=>$empRows, 'attendance'=>$attMap, 'start'=>$start, 'end'=>$end]);
    break;
  }
  case 'upsert_day': {
    ensure_admin();
    if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message'=>'Invalid CSRF'],400);
    $employee_id = (int)($_POST['employee_id'] ?? 0);
    $date = $_POST['date'] ?? '';
    $status = $_POST['status'] ?? 'present';
    $check_in = $_POST['check_in'] ?? null; if ($check_in==='') $check_in = null;
    $check_out = $_POST['check_out'] ?? null; if ($check_out==='') $check_out = null;
    $hours_worked = ($_POST['hours_worked'] ?? '')!=='' ? (float)$_POST['hours_worked'] : null;
    $late_minutes = ($_POST['late_minutes'] ?? '')!=='' ? (int)$_POST['late_minutes'] : null;
    $ot_minutes = ($_POST['ot_minutes'] ?? '')!=='' ? (int)$_POST['ot_minutes'] : null;
    $notes = trim($_POST['notes'] ?? ''); if ($notes==='') $notes = null;

    // Default times for present status when not provided
    if ($status === 'present') {
      if ($check_in === null) {
        $check_in = '08:00:00';
      }
      if ($check_out === null) {
        $check_out = '17:00:00';
      }
    }
    if (!$employee_id || !$date) json_response(['message'=>'Missing fields'],400);
    // derive branch from employee
    $br = $db->query('SELECT branch_id FROM employees WHERE id='.(int)$employee_id.' LIMIT 1');
    $branch_id = ($br && ($b=$br->fetch_assoc())) ? ($b['branch_id'] ?? null) : null;
    if ($hours_worked===null) $hours_worked = calc_hours($check_in, $check_out);
    // upsert
    $stmt = $db->prepare("INSERT INTO employees_attendance (employee_id, att_date, status, check_in, check_out, hours_worked, late_minutes, ot_minutes, notes, branch_id) VALUES (?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE status=VALUES(status), check_in=VALUES(check_in), check_out=VALUES(check_out), hours_worked=VALUES(hours_worked), late_minutes=VALUES(late_minutes), ot_minutes=VALUES(ot_minutes), notes=VALUES(notes), branch_id=VALUES(branch_id)");
    $stmt->bind_param('issssdiisi', $employee_id, $date, $status, $check_in, $check_out, $hours_worked, $late_minutes, $ot_minutes, $notes, $branch_id);
    if (!$stmt->execute()) json_response(['message'=>$stmt->error],500);
    json_response(['message'=>'Saved']);
    break;
  }
  case 'month_summary': {
    $month = (int)($_GET['month'] ?? date('n'));
    $year = (int)($_GET['year'] ?? date('Y'));
    $branch_id = isset($_GET['branch_id']) && $_GET['branch_id']!=='' ? (int)$_GET['branch_id'] : 0;
    $start = sprintf('%04d-%02d-01',$year,$month);
    $end = date('Y-m-t', strtotime($start));
    $where = "WHERE a.att_date BETWEEN ? AND ?";
    $types = 'ss'; $params = [$start, $end];
    if ($branch_id) { $where .= ' AND e.branch_id=?'; $types.='i'; $params[]=$branch_id; }
    $sql = "SELECT e.id AS employee_id, e.emp_code, e.full_name,
      SUM(CASE WHEN a.status='present' THEN 1 ELSE 0 END) AS present_days,
      SUM(CASE WHEN a.status='half_day' THEN 1 ELSE 0 END) AS halfday_days,
      SUM(CASE WHEN a.status='short_leave' THEN 1 ELSE 0 END) AS short_leave_days,
      SUM(CASE WHEN a.status='absent' THEN 1 ELSE 0 END) AS absent_days,
      SUM(CASE WHEN a.status='leave' THEN 1 ELSE 0 END) AS leave_days,
      SUM(CASE WHEN a.status='holiday' THEN 1 ELSE 0 END) AS holiday_days,
      COALESCE(SUM(a.hours_worked),0) AS hours_total,
      COALESCE(SUM(a.late_minutes),0) AS late_total,
      COALESCE(SUM(a.ot_minutes),0) AS ot_total
      FROM employees_attendance a
      JOIN employees e ON e.id=a.employee_id
      $where
      GROUP BY e.id, e.emp_code, e.full_name
      ORDER BY e.emp_code";
    $stmt=$db->prepare($sql);
    $stmt->bind_param($types, ...$params);
    $stmt->execute(); $res=$stmt->get_result();
    $rows=[]; while($r=$res->fetch_assoc()){ $rows[]=$r; }
    json_response(['data'=>$rows]);
    break;
  }
  default:
    json_response(['message'=>'Invalid action'],400);
}
