<?php
declare(strict_types=1);

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Accept');

ob_start();

function respond(int $status_code, array $payload): void
{
    while (ob_get_level() > 0) {
        ob_end_clean();
    }

    http_response_code($status_code);
    echo json_encode($payload);
    exit;
}

if (($_SERVER['REQUEST_METHOD'] ?? '') === 'OPTIONS') {
    respond(204, []);
}

if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
    respond(405, [
        'success' => false,
        'message' => 'Method tidak dibenarkan.',
    ]);
}

require_once __DIR__ . '/../db.php';

$raw = file_get_contents('php://input');
$payload = json_decode($raw ?: '', true);
if (!is_array($payload)) {
    $payload = $_POST;
}

$user_id = (int) ($payload['user_id'] ?? 0);
if ($user_id <= 0) {
    respond(422, [
        'success' => false,
        'message' => 'User tidak sah.',
    ]);
}

$user_stmt = mysqli_prepare($conn, 'SELECT id FROM users WHERE id = ? AND status = "approved" LIMIT 1');
if (!$user_stmt) {
    respond(500, [
        'success' => false,
        'message' => 'Ralat sistem semasa membaca pengguna.',
    ]);
}

mysqli_stmt_bind_param($user_stmt, 'i', $user_id);
mysqli_stmt_execute($user_stmt);
$user_result = mysqli_stmt_get_result($user_stmt);
if (!$user_result || !mysqli_fetch_assoc($user_result)) {
    respond(403, [
        'success' => false,
        'message' => 'Akaun tidak dibenarkan.',
    ]);
}

$action = strtolower(trim((string) ($payload['action'] ?? 'list')));

function normalizeCalendarType(string $type): string
{
    $value = strtolower(trim($type));
    $value = str_replace('-', '_', $value);
    $allowed = ['task', 'meeting', 'event', 'leave', 'reminder', 'time_off'];
    return in_array($value, $allowed, true) ? $value : 'event';
}

function normalizeCalendarStatus(string $status, string $type): string
{
    $value = trim($status);
    if ($value !== '') {
        return substr($value, 0, 50);
    }

    return match ($type) {
        'task' => 'Pending',
        'meeting' => 'Confirmed',
        'leave', 'time_off' => 'Pending',
        'reminder' => 'Pending',
        default => 'Scheduled',
    };
}

function normalizeCalendarDateTime(string $value): ?string
{
    $trimmed = trim($value);
    if ($trimmed === '') {
        return null;
    }

    try {
        $date = new DateTime($trimmed);
        return $date->format('Y-m-d H:i:s');
    } catch (Throwable $exception) {
        return null;
    }
}

function calendarTimeLabel(array $row): string
{
    if ((int) ($row['is_full_day'] ?? 0) === 1) {
        return 'Full Day';
    }

    $start = trim((string) ($row['start_at'] ?? ''));
    $end = trim((string) ($row['end_at'] ?? ''));
    if ($start === '') {
        return '';
    }

    try {
        $start_date = new DateTime($start);
        if ($end !== '') {
            $end_date = new DateTime($end);
            if ($start_date->format('Y-m-d') === $end_date->format('Y-m-d')) {
                return $start_date->format('g:i A') . ' - ' . $end_date->format('g:i A');
            }
        }

        return $start_date->format('g:i A');
    } catch (Throwable $exception) {
        return $start;
    }
}

function calendarDateLabel(array $row): string
{
    $start = trim((string) ($row['start_at'] ?? ''));
    if ($start === '') {
        return '';
    }

    try {
        return (new DateTime($start))->format('Y-m-d');
    } catch (Throwable $exception) {
        return $start;
    }
}

function mapCalendarEvent(array $row): array
{
    $participants = [];
    $raw_participants = trim((string) ($row['participants'] ?? ''));
    if ($raw_participants !== '') {
        $decoded = json_decode($raw_participants, true);
        if (is_array($decoded)) {
            $participants = array_values(array_map('strval', $decoded));
        }
    }

    return [
        'id' => (int) ($row['id'] ?? 0),
        'userId' => (int) ($row['user_id'] ?? 0),
        'type' => (string) ($row['event_type'] ?? 'event'),
        'title' => (string) ($row['title'] ?? ''),
        'description' => (string) ($row['description'] ?? ''),
        'location' => (string) ($row['location'] ?? ''),
        'startAt' => (string) ($row['start_at'] ?? ''),
        'endAt' => (string) ($row['end_at'] ?? ''),
        'isFullDay' => ((int) ($row['is_full_day'] ?? 0)) === 1,
        'priority' => (string) ($row['priority'] ?? ''),
        'status' => (string) ($row['status'] ?? ''),
        'reason' => (string) ($row['reason'] ?? ''),
        'participants' => $participants,
        'dateLabel' => calendarDateLabel($row),
        'timeLabel' => calendarTimeLabel($row),
        'dueDate' => (string) ($row['due_date'] ?? ''),
        'manday' => (int) ($row['manday'] ?? 0),
        'createdAt' => (string) ($row['created_at'] ?? ''),
    ];
}

if ($action === 'participants') {
    $participants_stmt = mysqli_prepare(
        $conn,
        'SELECT id, fullname, short_name, email, department, position, profile_photo
         FROM users
         WHERE status = "approved"
         ORDER BY fullname ASC, short_name ASC'
    );

    if (!$participants_stmt) {
        respond(500, [
            'success' => false,
            'message' => 'Senarai pengguna tidak dapat dimuatkan.',
        ]);
    }

    mysqli_stmt_execute($participants_stmt);
    $participants_result = mysqli_stmt_get_result($participants_stmt);
    $participants = [];

    if ($participants_result) {
        while ($participant = mysqli_fetch_assoc($participants_result)) {
            $participants[] = [
                'id' => (int) ($participant['id'] ?? 0),
                'fullname' => (string) ($participant['fullname'] ?? ''),
                'short_name' => (string) ($participant['short_name'] ?? ''),
                'email' => (string) ($participant['email'] ?? ''),
                'department' => (string) ($participant['department'] ?? ''),
                'position' => (string) ($participant['position'] ?? ''),
                'profile_photo' => (string) ($participant['profile_photo'] ?? ''),
            ];
        }
    }

    respond(200, [
        'success' => true,
        'participants' => $participants,
    ]);
}

if ($action === 'update_status') {
    $event_id = (int) ($payload['event_id'] ?? $payload['eventId'] ?? 0);
    $status = strtolower(trim((string) ($payload['status'] ?? '')));
    $allowed_statuses = ['dump', 'ongoing', 'completed'];

    if ($event_id <= 0 || !in_array($status, $allowed_statuses, true)) {
        respond(422, [
            'success' => false,
            'message' => 'Status task tidak sah.',
        ]);
    }

    $stmt = mysqli_prepare(
        $conn,
        'UPDATE calendar_events
         SET status = ?, updated_by = ?, updated_at = NOW()
         WHERE id = ? AND user_id = ? AND event_type = "task" AND deleted_at IS NULL'
    );
    mysqli_stmt_bind_param($stmt, 'siii', $status, $user_id, $event_id, $user_id);
    mysqli_stmt_execute($stmt);

    if (mysqli_stmt_affected_rows($stmt) < 1) {
        respond(404, [
            'success' => false,
            'message' => 'Task tidak ditemui atau status telah dikemas kini.',
        ]);
    }

    respond(200, [
        'success' => true,
        'message' => 'Status task berjaya dikemas kini.',
    ]);
}

if ($action === 'update') {
    $event_id = (int) ($payload['event_id'] ?? $payload['eventId'] ?? 0);
    $title = trim((string) ($payload['title'] ?? ''));
    $description = trim((string) ($payload['description'] ?? ''));
    $start_at = normalizeCalendarDateTime((string) ($payload['start_at'] ?? $payload['startAt'] ?? ''));
    $end_at = normalizeCalendarDateTime((string) ($payload['end_at'] ?? $payload['endAt'] ?? ''));
    $priority = strtolower(trim((string) ($payload['priority'] ?? '')));
    $priority = in_array($priority, ['low', 'medium', 'high'], true) ? $priority : null;
    $due_date = normalizeCalendarDateTime((string) ($payload['due_date'] ?? $payload['dueDate'] ?? ''));
    $due_date = $due_date !== null ? substr($due_date, 0, 10) : null;
    $manday = max(0, (int) ($payload['manday'] ?? 0));

    if ($event_id <= 0 || $title === '' || $start_at === null || $due_date === null) {
        respond(422, [
            'success' => false,
            'message' => 'Maklumat task tidak lengkap.',
        ]);
    }

    $stmt = mysqli_prepare(
        $conn,
        'UPDATE calendar_events
         SET title = ?, description = ?, start_at = ?, end_at = ?, due_date = ?,
             manday = ?, priority = ?,
             updated_by = ?, updated_at = NOW()
         WHERE id = ? AND user_id = ? AND event_type = "task" AND deleted_at IS NULL'
    );
    mysqli_stmt_bind_param(
        $stmt,
        'sssssisiii',
        $title,
        $description,
        $start_at,
        $end_at,
        $due_date,
        $manday,
        $priority,
        $user_id,
        $event_id,
        $user_id
    );
    mysqli_stmt_execute($stmt);

    if (mysqli_stmt_affected_rows($stmt) < 0) {
        respond(500, [
            'success' => false,
            'message' => 'Task gagal dikemas kini.',
        ]);
    }

    $fetch = mysqli_prepare(
        $conn,
        'SELECT * FROM calendar_events
         WHERE id = ? AND user_id = ? AND event_type = "task" AND deleted_at IS NULL
         LIMIT 1'
    );
    mysqli_stmt_bind_param($fetch, 'ii', $event_id, $user_id);
    mysqli_stmt_execute($fetch);
    $result = mysqli_stmt_get_result($fetch);
    $row = $result ? mysqli_fetch_assoc($result) : null;

    if (!$row) {
        respond(404, [
            'success' => false,
            'message' => 'Task tidak ditemui.',
        ]);
    }

    respond(200, [
        'success' => true,
        'message' => 'Task berjaya dikemas kini.',
        'event' => mapCalendarEvent($row),
    ]);
}

if ($action === 'delete') {
    $event_id = (int) ($payload['event_id'] ?? $payload['eventId'] ?? 0);
    if ($event_id <= 0) {
        respond(422, [
            'success' => false,
            'message' => 'Task tidak sah.',
        ]);
    }

    $stmt = mysqli_prepare(
        $conn,
        'UPDATE calendar_events
         SET deleted_at = NOW(), updated_by = ?, updated_at = NOW()
         WHERE id = ? AND user_id = ? AND event_type = "task" AND deleted_at IS NULL'
    );
    mysqli_stmt_bind_param($stmt, 'iii', $user_id, $event_id, $user_id);
    mysqli_stmt_execute($stmt);

    if (mysqli_stmt_affected_rows($stmt) < 1) {
        respond(404, [
            'success' => false,
            'message' => 'Task tidak ditemui atau telah dipadam.',
        ]);
    }

    respond(200, [
        'success' => true,
        'message' => 'Task berjaya dipadam.',
    ]);
}

if ($action === 'create') {
    $type = normalizeCalendarType((string) ($payload['type'] ?? 'event'));
    $title = trim((string) ($payload['title'] ?? ''));
    $description = trim((string) ($payload['description'] ?? ''));
    $location = trim((string) ($payload['location'] ?? ''));
    $start_at = normalizeCalendarDateTime((string) ($payload['start_at'] ?? $payload['startAt'] ?? ''));
    $end_at = normalizeCalendarDateTime((string) ($payload['end_at'] ?? $payload['endAt'] ?? ''));
    $is_full_day = !empty($payload['is_full_day']) || !empty($payload['isFullDay']) ? 1 : 0;
    $priority = strtolower(trim((string) ($payload['priority'] ?? '')));
    $priority = in_array($priority, ['low', 'medium', 'high'], true) ? $priority : null;
    $due_date = normalizeCalendarDateTime((string) ($payload['due_date'] ?? $payload['dueDate'] ?? ''));
    $due_date = $due_date !== null ? substr($due_date, 0, 10) : null;
    $manday = max(0, (int) ($payload['manday'] ?? 0));
    $status = normalizeCalendarStatus((string) ($payload['status'] ?? ''), $type);
    $reason = trim((string) ($payload['reason'] ?? ''));
    $participants = $payload['participants'] ?? [];
    $participants_json = is_array($participants)
        ? json_encode(array_values(array_map('strval', $participants)))
        : null;

    if ($title === '') {
        respond(422, [
            'success' => false,
            'message' => 'Tajuk calendar diperlukan.',
        ]);
    }

    if ($start_at === null) {
        respond(422, [
            'success' => false,
            'message' => 'Tarikh mula tidak sah.',
        ]);
    }

    if ($type === 'task' && $due_date === null) {
        respond(422, [
            'success' => false,
            'message' => 'Due Date task diperlukan.',
        ]);
    }

    $stmt = mysqli_prepare(
        $conn,
        'INSERT INTO calendar_events
            (user_id, event_type, title, description, location, start_at, end_at, due_date, manday,
             is_full_day, priority, status, reason, participants, created_by, updated_by)
         VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'
    );

    if (!$stmt) {
        respond(500, [
            'success' => false,
            'message' => 'Ralat sistem semasa menyediakan calendar.',
        ]);
    }

    mysqli_stmt_bind_param(
        $stmt,
        'isssssssiissssii',
        $user_id,
        $type,
        $title,
        $description,
        $location,
        $start_at,
        $end_at,
        $due_date,
        $manday,
        $is_full_day,
        $priority,
        $status,
        $reason,
        $participants_json,
        $user_id,
        $user_id
    );

    if (!mysqli_stmt_execute($stmt)) {
        respond(500, [
            'success' => false,
            'message' => 'Calendar gagal disimpan.',
        ]);
    }

    $event_id = (int) mysqli_insert_id($conn);
    $fetch = mysqli_prepare($conn, 'SELECT * FROM calendar_events WHERE id = ? AND user_id = ? LIMIT 1');
    mysqli_stmt_bind_param($fetch, 'ii', $event_id, $user_id);
    mysqli_stmt_execute($fetch);
    $result = mysqli_stmt_get_result($fetch);
    $row = $result ? mysqli_fetch_assoc($result) : null;

    respond(200, [
        'success' => true,
        'message' => 'Calendar berjaya disimpan.',
        'event' => $row ? mapCalendarEvent($row) : null,
    ]);
}

$stmt = mysqli_prepare(
    $conn,
    'SELECT * FROM calendar_events
     WHERE user_id = ? AND deleted_at IS NULL
     ORDER BY start_at ASC, id ASC'
);
if (!$stmt) {
    respond(500, [
        'success' => false,
        'message' => 'Ralat sistem semasa membaca calendar.',
    ]);
}

mysqli_stmt_bind_param($stmt, 'i', $user_id);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$events = [];
while ($row = $result ? mysqli_fetch_assoc($result) : null) {
    $events[] = mapCalendarEvent($row);
}

respond(200, [
    'success' => true,
    'message' => 'Calendar berjaya dimuatkan.',
    'events' => $events,
]);
