<?php

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, Authorization");

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit();
}

// ============================================================
// ERROR HANDLING
//
// If config.php enables mysqli_report(MYSQLI_REPORT_ERROR |
// MYSQLI_REPORT_STRICT), any failed query throws an uncaught
// mysqli_sql_exception instead of returning false. These two
// handlers make sure we ALWAYS return JSON with the real error
// message instead of a blank HTTP 500.
// ============================================================

error_reporting(E_ALL);
ini_set('display_errors', '0');
ini_set('log_errors', '1');

set_exception_handler(function ($e) {

    if (!headers_sent()) {
        header("Content-Type: application/json; charset=UTF-8");
        http_response_code(500);
    }

    echo json_encode([
        "success" => false,
        "message" => "Server PHP error.",
        "error" => $e->getMessage(),
        "file" => basename($e->getFile()),
        "line" => $e->getLine()
    ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

    exit();
});

register_shutdown_function(function () {

    $error = error_get_last();

    if (
        $error !== null &&
        in_array(
            $error['type'],
            [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR],
            true
        )
    ) {

        if (!headers_sent()) {
            header("Content-Type: application/json; charset=UTF-8");
            http_response_code(500);
        }

        echo json_encode([
            "success" => false,
            "message" => "PHP Fatal Error",
            "error" => $error['message'],
            "file" => basename($error['file']),
            "line" => $error['line']
        ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    }
});

// ============================================================
// DATABASE CONNECTION
// ============================================================

require_once '../config.php';

// ============================================================
// ONLY POST
// ============================================================

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {

    http_response_code(405);

    echo json_encode([
        "success" => false,
        "message" => "Only POST method is allowed."
    ]);

    exit();
}

// ============================================================
// GET JSON INPUT
// ============================================================

$rawData = file_get_contents("php://input");

$data = json_decode($rawData, true);

if (!is_array($data)) {
    $data = $_POST;
}

// ============================================================
// INPUT
// ============================================================

$action = trim(
    $data['action'] ?? 'list'
);

// ============================================================
// GET USER ID
//
// IMPORTANT:
// users.id is VARCHAR (e.g. EMP028, EMP031, BS05).
// Never convert this value to int.
//
// ------------------------------------------------------------
// SCHEMA NOTE:
//
// notifications.employee_id is currently defined as INT(11)
// in the database. If that column still only ever stores
// plain numbers, it will NOT correctly match VARCHAR employee
// IDs like "EMP031" — any bind as a string against a real INT
// column will be coerced by MySQL and can silently match the
// wrong rows (or none at all).
//
// To keep this table consistent with users.id / daily_reports
// .user_id / notification_reads.user_id (all VARCHAR), run:
//
//   ALTER TABLE notifications
//   MODIFY employee_id VARCHAR(11) NOT NULL;
//
// and make sure whatever inserts rows into `notifications`
// writes the full employee ID string (e.g. "EMP031"), not a
// bare number.
// ------------------------------------------------------------
// ============================================================

$userId = trim(
    (string)(
        $data['user_id'] ?? ''
    )
);

// ============================================================
// VALIDATE USER
// ============================================================

if ($userId === '') {

    http_response_code(400);

    echo json_encode([
        "success" => false,
        "message" => "Valid user_id is required."
    ]);

    exit();
}

// ============================================================
// GET USER INFORMATION
// ============================================================

$userStmt = $conn->prepare("
    SELECT
        id,
        username,
        role
    FROM users
    WHERE id = ?
    LIMIT 1
");

if (!$userStmt) {

    http_response_code(500);

    echo json_encode([
        "success" => false,
        "message" => "Unable to process user request."
    ]);

    exit();
}

$userStmt->bind_param(
    "s",
    $userId
);

$userStmt->execute();

$userResult =
    $userStmt->get_result();

if ($userResult->num_rows === 0) {

    $userStmt->close();

    http_response_code(404);

    echo json_encode([
        "success" => false,
        "message" => "User not found."
    ]);

    exit();
}

$user =
    $userResult->fetch_assoc();

$userStmt->close();

// ============================================================
// ACTION: LIST
//
// notifications table (ACTUAL schema):
//
// id, message, type, employee_id, status, created_at,
// is_deleted, deleted_at
//
// Each row already belongs to exactly one employee via
// employee_id, and its own read/unread state via status
// ('Read' / 'Unread') — there is no title, no broadcast
// target_type/target_value, and no expires_at/is_active.
// ============================================================

if ($action === 'list') {

    $sql = "
        SELECT
            id,
            message,
            type,
            status,
            created_at
        FROM notifications
        WHERE
            employee_id = ?
            AND (
                is_deleted IS NULL
                OR is_deleted = 0
            )
        ORDER BY
            created_at DESC,
            id DESC
        LIMIT 100
    ";

    $stmt =
        $conn->prepare(
            $sql
        );

    if (!$stmt) {

        http_response_code(500);

        echo json_encode([
            "success" => false,
            "message" => "Unable to load notifications.",
            "error" => $conn->error
        ]);

        exit();
    }

    $stmt->bind_param(
        "s",
        $userId
    );

    $stmt->execute();

    $result =
        $stmt->get_result();

    $notifications = [];

    $unreadCount = 0;

    while (
        $row =
            $result->fetch_assoc()
    ) {

        $isRead =
            strtolower(
                trim(
                    (string)(
                        $row['status'] ?? ''
                    )
                )
            ) === 'read';

        if (!$isRead) {
            $unreadCount++;
        }

        $notifications[] = [

            "id" =>
                (int) $row['id'],

            // No "title" column exists. Use a simple,
            // human-readable label derived from "type" so the
            // Flutter UI still has something to show as a
            // heading.
            "title" =>
                ucwords(
                    str_replace(
                        ['_', '-'],
                        ' ',
                        (string)(
                            $row['type'] ?? 'general'
                        )
                    )
                ),

            "message" =>
                $row['message'],

            "type" =>
                $row['type'],

            "created_at" =>
                $row['created_at'],

            "is_read" =>
                $isRead ? 1 : 0
        ];
    }

    $stmt->close();

    echo json_encode([
        "success" => true,

        "message" =>
            "Notifications loaded successfully.",

        "unread_count" =>
            $unreadCount,

        "notifications" =>
            $notifications
    ]);

    $conn->close();

    exit();
}

// ============================================================
// ACTION: MARK ONE AS READ
//
// Updates the row's own status column directly. Also scoped
// to employee_id so one employee can never mark another
// employee's notification as read.
// ============================================================

if ($action === 'mark_read') {

    $notificationId =
        intval(
            $data['notification_id'] ?? 0
        );

    if ($notificationId <= 0) {

        http_response_code(400);

        echo json_encode([
            "success" => false,
            "message" =>
                "Valid notification_id is required."
        ]);

        exit();
    }

    // ========================================================
    // CHECK NOTIFICATION EXISTS AND BELONGS TO THIS EMPLOYEE
    // ========================================================

    $checkStmt =
        $conn->prepare("
            SELECT id
            FROM notifications
            WHERE id = ?
              AND employee_id = ?
              AND (
                  is_deleted IS NULL
                  OR is_deleted = 0
              )
            LIMIT 1
        ");

    if (!$checkStmt) {

        http_response_code(500);

        echo json_encode([
            "success" => false,
            "message" =>
                "Unable to process notification."
        ]);

        exit();
    }

    $checkStmt->bind_param(
        "is",
        $notificationId,
        $userId
    );

    $checkStmt->execute();

    $checkResult =
        $checkStmt->get_result();

    if (
        $checkResult->num_rows === 0
    ) {

        $checkStmt->close();

        http_response_code(404);

        echo json_encode([
            "success" => false,
            "message" =>
                "Notification not found."
        ]);

        exit();
    }

    $checkStmt->close();

    // ========================================================
    // UPDATE STATUS -> 'Read'
    // ========================================================

    $stmt =
        $conn->prepare("
            UPDATE notifications
            SET status = 'Read'
            WHERE id = ?
              AND employee_id = ?
        ");

    if (!$stmt) {

        http_response_code(500);

        echo json_encode([
            "success" => false,
            "message" =>
                "Unable to mark notification as read."
        ]);

        exit();
    }

    $stmt->bind_param(
        "is",
        $notificationId,
        $userId
    );

    $stmt->execute();

    $stmt->close();

    echo json_encode([
        "success" => true,
        "message" =>
            "Notification marked as read."
    ]);

    $conn->close();

    exit();
}

// ============================================================
// ACTION: MARK ALL AS READ
// ============================================================

if ($action === 'mark_all_read') {

    $stmt =
        $conn->prepare("
            UPDATE notifications
            SET status = 'Read'
            WHERE employee_id = ?
              AND status = 'Unread'
              AND (
                  is_deleted IS NULL
                  OR is_deleted = 0
              )
        ");

    if (!$stmt) {

        http_response_code(500);

        echo json_encode([
            "success" => false,
            "message" =>
                "Unable to mark notifications as read.",
            "error" => $conn->error
        ]);

        exit();
    }

    $stmt->bind_param(
        "s",
        $userId
    );

    $stmt->execute();

    $stmt->close();

    echo json_encode([
        "success" => true,
        "message" =>
            "All notifications marked as read."
    ]);

    $conn->close();

    exit();
}

// ============================================================
// INVALID ACTION
// ============================================================

http_response_code(400);

echo json_encode([
    "success" => false,
    "message" =>
        "Invalid action. Allowed actions: list, mark_read, mark_all_read."
]);

$conn->close();

exit();

?>