<?php
// POST /api/calendar/events.php
require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/../config/auth.php';

$user  = requireAuth();
$db    = getDB();
$uid   = (int)$user['id'];
$role  = (int)$user['role_id'];

$year  = (int)post('year',  date('Y'));
$month = (int)post('month', date('n'));

$from = sprintf('%04d-%02d-01', $year, $month);
$to   = date('Y-m-t', strtotime($from));

// ── Filter resolution ─────────────────────────────────────
// Only admin (1) and dev (2) may request wider views.
// $filterAll  = true  → show everything (no user restriction)
// $filterUid  = the user ID to filter by (own or impersonated)
$isPrivileged = ($role == 1 || $role == 2);
$viewAll      = $isPrivileged && post('view_all');
$viewUserId   = $isPrivileged && post('view_user_id') ? (int)post('view_user_id') : null;

if ($viewAll)        { $filterAll = true;  $filterUid = $uid; }
elseif ($viewUserId) { $filterAll = false; $filterUid = $viewUserId; }
else                 { $filterAll = false; $filterUid = $uid; }   // My Events — even admin only sees their own

$events = [];
$errors = [];

// ── 1. Job Cards ──────────────────────────────────────────
try {
    if ($filterAll) {
        $stmt = $db->prepare("
            SELECT jc.id, jc.job_number, jc.title,
                   jc.scheduled_date AS event_date, jc.scheduled_time AS event_time,
                   jc.priority, jc.status, jc.site_name, jc.site_address,
                   COALESCE(
                     GROUP_CONCAT(DISTINCT tu.full_name ORDER BY tu.full_name SEPARATOR ', '),
                     au.full_name
                   ) AS assigned_user
            FROM job_cards jc
            LEFT JOIN users au ON au.id = jc.assigned_to
            LEFT JOIN job_card_technicians jct2 ON jct2.job_card_id = jc.id
            LEFT JOIN users tu ON tu.id = jct2.user_id
            WHERE jc.scheduled_date BETWEEN ? AND ? AND jc.status NOT IN ('cancelled')
            GROUP BY jc.id
            ORDER BY jc.scheduled_date, jc.scheduled_time
        ");
        $stmt->execute([$from, $to]);
    } else {
        // Only jobs assigned to or involving $filterUid
        $stmt = $db->prepare("
            SELECT jc.id, jc.job_number, jc.title,
                   jc.scheduled_date AS event_date, jc.scheduled_time AS event_time,
                   jc.priority, jc.status, jc.site_name, jc.site_address,
                   COALESCE(
                     GROUP_CONCAT(DISTINCT tu.full_name ORDER BY tu.full_name SEPARATOR ', '),
                     au.full_name
                   ) AS assigned_user
            FROM job_cards jc
            LEFT JOIN users au ON au.id = jc.assigned_to
            LEFT JOIN job_card_technicians jct2 ON jct2.job_card_id = jc.id
            LEFT JOIN users tu ON tu.id = jct2.user_id
            WHERE jc.scheduled_date BETWEEN ? AND ? AND jc.status NOT IN ('cancelled')
              AND (jc.assigned_to = ? OR jct2.user_id = ?)
            GROUP BY jc.id
            ORDER BY jc.scheduled_date, jc.scheduled_time
        ");
        $stmt->execute([$from, $to, $filterUid, $filterUid]);
    }
    foreach ($stmt->fetchAll() as $r) {
        $events[] = [
            'id'       => 'jc-' . $r['id'],
            'type'     => 'jobcard',
            'label'    => ($r['job_number'] ?? '') . ' — ' . $r['title'],
            'sub'      => $r['site_name'] ?? $r['site_address'] ?? null,
            'date'     => $r['event_date'],
            'time'     => !empty($r['event_time']) ? substr($r['event_time'], 0, 5) : null,
            'priority' => $r['priority'],
            'status'   => $r['status'],
            'link'     => ['page' => 'jobcards', 'id' => (int)$r['id']],
            'color'    => 'blue',
            'assigned_user' => $r['assigned_user'] ?? null,
        ];
    }
} catch (Exception $e) { $errors[] = 'jobcards: ' . $e->getMessage(); }

// ── 2. Project Todos ──────────────────────────────────────
try {
    if ($role != 4) {  // Techs don't do project todos
        if ($filterAll) {
            $stmt = $db->prepare("
                SELECT t.id, t.title, t.due_date AS event_date, t.priority, t.status,
                       p.name AS project_name, p.id AS project_id
                FROM project_todos t
                JOIN project_sections s ON s.id = t.section_id
                JOIN projects p ON p.id = s.project_id
                WHERE t.due_date BETWEEN ? AND ? AND t.status != 'cancelled'
                ORDER BY t.due_date
            ");
            $stmt->execute([$from, $to]);
        } else {
            $stmt = $db->prepare("
                SELECT t.id, t.title, t.due_date AS event_date, t.priority, t.status,
                       p.name AS project_name, p.id AS project_id
                FROM project_todos t
                JOIN project_sections s ON s.id = t.section_id
                JOIN projects p ON p.id = s.project_id
                WHERE t.due_date BETWEEN ? AND ? AND t.status != 'cancelled'
                  AND t.assigned_to = ?
                ORDER BY t.due_date
            ");
            $stmt->execute([$from, $to, $filterUid]);
        }
        foreach ($stmt->fetchAll() as $r) {
            $events[] = [
                'id'       => 'todo-' . $r['id'],
                'type'     => 'todo',
                'label'    => $r['title'],
                'sub'      => $r['project_name'],
                'date'     => $r['event_date'],
                'time'     => null,
                'priority' => $r['priority'],
                'status'   => $r['status'],
                'link'     => ['page' => 'projects', 'id' => (int)$r['project_id']],
                'color'    => 'purple',
            ];
        }
    }
} catch (Exception $e) { $errors[] = 'todos: ' . $e->getMessage(); }

// ── 3. Leave ─────────────────────────────────────────────
try {
    if ($filterAll) {
        $stmt = $db->prepare("
            SELECT l.id, l.leave_type, l.start_date, l.end_date, l.days,
                   CONCAT(e.first_name,' ',e.last_name) AS emp_name
            FROM employee_leave l
            JOIN employees e ON e.id = l.employee_id
            WHERE l.status = 'approved' AND l.start_date <= ? AND l.end_date >= ?
        ");
        $stmt->execute([$to, $from]);
    } else {
        $stmt = $db->prepare("
            SELECT l.id, l.leave_type, l.start_date, l.end_date, l.days,
                   CONCAT(e.first_name,' ',e.last_name) AS emp_name
            FROM employee_leave l
            JOIN employees e ON e.id = l.employee_id
            WHERE l.status = 'approved' AND l.start_date <= ? AND l.end_date >= ?
              AND e.user_id = ?
        ");
        $stmt->execute([$to, $from, $filterUid]);
    }
    foreach ($stmt->fetchAll() as $r) {
        $start = max($r['start_date'], $from);
        $end   = min($r['end_date'],   $to);
        $cur   = strtotime($start);
        $endTs = strtotime($end);
        while ($cur <= $endTs) {
            $events[] = [
                'id'    => 'leave-' . $r['id'] . '-' . date('Ymd', $cur),
                'type'  => 'leave',
                'label' => ucfirst($r['leave_type']) . ' Leave — ' . $r['emp_name'],
                'sub'   => $r['days'] . ' day(s)',
                'date'  => date('Y-m-d', $cur),
                'time'  => null,
                'color' => 'orange',
                'link'  => null,
            ];
            $cur = strtotime('+1 day', $cur);
        }
    }
} catch (Exception $e) { $errors[] = 'leave: ' . $e->getMessage(); }

// ── 4. Project Target Dates ───────────────────────────────
try {
    if ($filterAll) {
        $stmt = $db->prepare("
            SELECT p.id, p.name, p.target_date AS event_date, p.status, p.priority
            FROM projects p
            WHERE p.target_date BETWEEN ? AND ?
              AND p.status NOT IN ('completed','cancelled')
        ");
        $stmt->execute([$from, $to]);
        foreach ($stmt->fetchAll() as $r) {
            $events[] = [
                'id'    => 'proj-' . $r['id'],
                'type'  => 'project',
                'label' => '🎯 ' . $r['name'],
                'sub'   => 'Target date',
                'date'  => $r['event_date'],
                'time'  => null,
                'link'  => ['page' => 'projects', 'id' => (int)$r['id']],
                'color' => 'green',
            ];
        }
    }
} catch (Exception $e) { $errors[] = 'projects: ' . $e->getMessage(); }

// ── 5. Custom Calendar Events ─────────────────────────────
try {
    // Always filter by owner (created_by = filterUid) or shared.
    // In filterAll mode admins still see shared + their own only for custom events
    // (custom events are personal; shared ones are visible to everyone)
    $stmt = $db->prepare("
        SELECT id, title, description, event_date, event_time,
               event_type, color, all_day, created_by, is_shared,
               COALESCE(is_complete, 0) AS is_complete
        FROM calendar_events
        WHERE event_date BETWEEN ? AND ?
          AND (created_by = ? OR is_shared = 1)
          AND title NOT LIKE '✅ Checklist:%'
        ORDER BY event_date, event_time
    ");
    $stmt->execute([$from, $to, $filterUid]);
    foreach ($stmt->fetchAll() as $r) {
        $events[] = [
            'id'       => 'evt-' . $r['id'],
            'type'     => $r['event_type'] ?: 'event',
            'label'    => $r['title'],
            'sub'      => $r['description'],
            'date'     => $r['event_date'],
            'time'     => (!empty($r['event_time']) && !$r['all_day']) ? substr($r['event_time'], 0, 5) : null,
            'color'    => $r['color'] ?: 'teal',
            'link'     => null,
            'editable' => (int)$r['created_by'] === $uid,
            'assigned_user' => null,
            'raw_id'   => (int)$r['id'],
            'status'   => $r['is_complete'] ? 'done' : null,
        ];
    }
} catch (Exception $e) { $errors[] = 'calendar_events: ' . $e->getMessage(); }

// ── 6. Checklist Instances ────────────────────────────────
try {
    if ($filterAll) {
        $clStmt = $db->prepare("
            SELECT ci.id, ci.due_date, ci.status, ci.user_id,
                   ct.name AS template_name, ct.linked_type
            FROM checklist_instances ci
            JOIN checklist_templates ct ON ct.id = ci.template_id
            WHERE ci.due_date BETWEEN ? AND ?
            ORDER BY ci.due_date
        ");
        $clStmt->execute([$from, $to]);
    } else {
        // Only instances assigned to $filterUid
        $clStmt = $db->prepare("
            SELECT ci.id, ci.due_date, ci.status, ci.user_id,
                   ct.name AS template_name, ct.linked_type
            FROM checklist_instances ci
            JOIN checklist_templates ct ON ct.id = ci.template_id
            WHERE ci.due_date BETWEEN ? AND ?
              AND (ci.user_id = ? OR ct.assigned_to = ?)
            ORDER BY ci.due_date
        ");
        $clStmt->execute([$from, $to, $filterUid, $filterUid]);
    }
    $statusIcons = ['pending' => '🕐', 'in_progress' => '🔄', 'completed' => '✅', 'missed' => '❌'];
    foreach ($clStmt->fetchAll() as $r) {
        $icon = $statusIcons[$r['status']] ?? '📋';
        $events[] = [
            'id'     => 'cl-' . $r['id'],
            'type'   => 'checklist',
            'label'  => $icon . ' ' . $r['template_name'],
            'sub'    => ucfirst(str_replace('_', ' ', $r['status'])),
            'date'   => $r['due_date'],
            'time'   => null,
            'status' => in_array($r['status'], ['completed']) ? 'completed' : ($r['status'] === 'missed' ? 'missed' : $r['status']),
            'link'   => ['page' => 'checklists', 'instance_id' => (int)$r['id']],
            'color'  => 'teal',
        ];
    }
} catch (Exception $e) { $errors[] = 'checklists: ' . $e->getMessage(); }

// ── 7. Document Expiry Dates (admin/privileged only) ──────
try {
    if ($filterAll) {
        $stmt = $db->prepare("SELECT cf.id, cf.description, cf.doc_type, cf.expiry_date, cf.client_id, cl.company_name AS entity_name FROM client_files cf JOIN clients cl ON cl.id = cf.client_id WHERE cf.expiry_date BETWEEN ? AND ? AND cf.expiry_date IS NOT NULL");
        $stmt->execute([$from, $to]);
        foreach ($stmt->fetchAll() as $r) {
            $events[] = ['id'=>'exp-cl-'.$r['id'],'type'=>'deadline','label'=>'📄 '.($r['description']?:$r['doc_type']).' — '.$r['entity_name'],'sub'=>'Client document expiry','date'=>$r['expiry_date'],'time'=>null,'status'=>null,'link'=>['page'=>'clients','id'=>(int)$r['client_id']],'color'=>'deadline'];
        }
        $stmt = $db->prepare("SELECT ed.id, ed.label, ed.doc_type, ed.expiry_date, ed.employee_id, CONCAT(e.first_name,' ',e.last_name) AS entity_name FROM employee_documents ed JOIN employees e ON e.id = ed.employee_id WHERE ed.expiry_date BETWEEN ? AND ? AND ed.expiry_date IS NOT NULL");
        $stmt->execute([$from, $to]);
        foreach ($stmt->fetchAll() as $r) {
            $events[] = ['id'=>'exp-emp-'.$r['id'],'type'=>'deadline','label'=>'📄 '.$r['label'].' — '.$r['entity_name'],'sub'=>'Employee document expiry','date'=>$r['expiry_date'],'time'=>null,'status'=>null,'link'=>['page'=>'employees','id'=>(int)$r['employee_id']],'color'=>'deadline'];
        }
        $stmt = $db->prepare("SELECT fd.id, fd.label, fd.doc_type, fd.expiry_date, fd.vehicle_id, CONCAT(v.make,' ',v.model,' (',v.registration,')') AS entity_name FROM fleet_documents fd JOIN fleet_vehicles v ON v.id = fd.vehicle_id WHERE fd.expiry_date BETWEEN ? AND ? AND fd.expiry_date IS NOT NULL");
        $stmt->execute([$from, $to]);
        foreach ($stmt->fetchAll() as $r) {
            $events[] = ['id'=>'exp-fl-'.$r['id'],'type'=>'deadline','label'=>'📄 '.$r['label'].' — '.$r['entity_name'],'sub'=>'Fleet document expiry','date'=>$r['expiry_date'],'time'=>null,'status'=>null,'link'=>['page'=>'fleet','id'=>(int)$r['vehicle_id']],'color'=>'deadline'];
        }
    }
} catch (Exception $e) { $errors[] = 'expiry_docs: '.$e->getMessage(); }

// ── 8. Meetings, Tasks & Reminders ───────────────────────────
try {
    if ($filterAll) {
        $mStmt = $db->prepare("
            SELECT m.id, m.type, m.title, m.meeting_date, m.start_time, m.status,
                   m.location, m.priority, m.created_by
            FROM meetings m
            WHERE m.meeting_date BETWEEN ? AND ?
              AND m.status NOT IN ('cancelled')
            ORDER BY m.meeting_date, m.start_time
        ");
        $mStmt->execute([$from, $to]);
    } else {
        $mStmt = $db->prepare("
            SELECT m.id, m.type, m.title, m.meeting_date, m.start_time, m.status,
                   m.location, m.priority, m.created_by
            FROM meetings m
            WHERE m.meeting_date BETWEEN ? AND ?
              AND m.status NOT IN ('cancelled')
              AND (m.created_by = ? OR EXISTS (
                SELECT 1 FROM meeting_attendees ma WHERE ma.meeting_id = m.id AND ma.user_id = ?
              ))
            ORDER BY m.meeting_date, m.start_time
        ");
        $mStmt->execute([$from, $to, $filterUid, $filterUid]);
    }

    $typeColors = [
        'internal' => 'blue',
        'client'   => 'green',
        'task'     => 'purple',
        'reminder' => 'reminder',
        'deadline' => 'deadline',
        'personal' => 'event',
    ];
    $typeIcons = [
        'internal' => '👥',
        'client'   => '🏢',
        'task'     => '✅',
        'reminder' => '🔔',
        'deadline' => '⚠️',
        'personal' => '👤',
    ];

    foreach ($mStmt->fetchAll() as $r) {
        $isDone = in_array($r['status'], ['completed']);
        $events[] = [
            'id'       => 'mtg-' . $r['id'],
            'type'     => in_array($r['type'], ['task','reminder','deadline']) ? $r['type'] : 'meeting',
            'label'    => ($typeIcons[$r['type']] ?? '📅') . ' ' . $r['title'],
            'sub'      => $r['location'] ?? null,
            'date'     => $r['meeting_date'],
            'time'     => !empty($r['start_time']) ? substr($r['start_time'], 0, 5) : null,
            'status'   => $isDone ? 'completed' : $r['status'],
            'priority' => $r['priority'],
            'link'     => ['page' => 'meetings', 'id' => (int)$r['id']],
            'color'    => $typeColors[$r['type']] ?? 'blue',
            'editable' => ((int)$r['created_by'] === $uid),
        ];
    }
} catch (Exception $e) { $errors[] = 'meetings: ' . $e->getMessage(); }

usort($events, function($a, $b) {
    return strcmp($a['date'] . ($a['time'] ?? '00:00'), $b['date'] . ($b['time'] ?? '00:00'));
});

apiSuccess([
    'events'       => $events,
    'month'        => $month,
    'year'         => $year,
    'from'         => $from,
    'to'           => $to,
    'debug_errors' => $errors,
]);