<?php

// ============================================================
// MANAGER REVIEW API
// File: api/manager_review.php
//
// Method: POST
//
// Review responsibility:
// {
//   "manager_id": 10,
//   "employee_id": 227,
//   "action": "responsibility_review",
//   "update_id": 15,
//   "manager_remarks": "Good work. Follow up tomorrow."
// }
//
// Approve KPI:
// {
//   "manager_id": 10,
//   "employee_id": 227,
//   "action": "kpi_approve",
//   "kpi_actual_id": 25,
//   "manager_comment": "Approved"
// }
//
// Reject KPI:
// {
//   "manager_id": 10,
//   "employee_id": 227,
//   "action": "kpi_reject",
//   "kpi_actual_id": 25,
//   "manager_comment": "Please correct actual value"
// }
//
// Supported actions:
// responsibility_review
// kpi_approve
// kpi_reject
// ============================================================

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

date_default_timezone_set('Asia/Kolkata');

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

require_once '../config.php';

// ============================================================
// RESPONSE
// ============================================================

function sendResponse(
    int $statusCode,
    bool $success,
    string $message,
    array $extra = []
): void {

    http_response_code($statusCode);

    echo json_encode(
        array_merge(
            [
                "success" => $success,
                "message" => $message
            ],
            $extra
        ),
        JSON_UNESCAPED_UNICODE |
        JSON_UNESCAPED_SLASHES
    );

    exit();
}

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

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

    sendResponse(
        405,
        false,
        "Only POST method is allowed."
    );
}

// ============================================================
// READ INPUT
// ============================================================

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

$data =
    json_decode(
        $rawData,
        true
    );

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

// ============================================================
// INPUTS
// ============================================================

$managerId =
    (int)($data['manager_id'] ?? 0);

$employeeId =
    (int)($data['employee_id'] ?? 0);

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

$updateId =
    (int)($data['update_id'] ?? 0);

$kpiActualId =
    (int)($data['kpi_actual_id'] ?? 0);

$managerRemarks =
    trim(
        $data['manager_remarks'] ?? ''
    );

$managerComment =
    trim(
        $data['manager_comment'] ?? ''
    );

// ============================================================
// BASIC VALIDATION
// ============================================================

if ($managerId <= 0) {

    $conn->close();

    sendResponse(
        400,
        false,
        "Valid manager_id is required."
    );
}

if ($employeeId <= 0) {

    $conn->close();

    sendResponse(
        400,
        false,
        "Valid employee_id is required."
    );
}

$allowedActions = [
    'responsibility_review',
    'kpi_approve',
    'kpi_reject'
];

if (
    !in_array(
        $action,
        $allowedActions,
        true
    )
) {

    $conn->close();

    sendResponse(
        400,
        false,
        "Invalid action."
    );
}

// ============================================================
// VALIDATE MANAGER
// ============================================================

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

if (!$stmt) {

    $conn->close();

    sendResponse(
        500,
        false,
        "Unable to validate manager."
    );
}

$stmt->bind_param(
    "i",
    $managerId
);

$stmt->execute();

$result =
    $stmt->get_result();

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

    $stmt->close();

    $conn->close();

    sendResponse(
        404,
        false,
        "Manager not found."
    );
}

$manager =
    $result->fetch_assoc();

$stmt->close();

$managerRole =
    strtolower(
        trim(
            $manager['role'] ?? ''
        )
    );

if ($managerRole !== 'manager') {

    $conn->close();

    sendResponse(
        403,
        false,
        "Only managers can perform this action."
    );
}

// ============================================================
// VERIFY EMPLOYEE BELONGS TO MANAGER
// ============================================================
//
// Assumption:
// users.reporting_manager_id = manager user ID
// ============================================================

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

if (!$stmt) {

    $conn->close();

    sendResponse(
        500,
        false,
        "Unable to validate employee reporting structure."
    );
}

$stmt->bind_param(
    "ii",
    $employeeId,
    $managerId
);

$stmt->execute();

$result =
    $stmt->get_result();

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

    $stmt->close();

    $conn->close();

    sendResponse(
        403,
        false,
        "This employee is not assigned to this manager."
    );
}

$employee =
    $result->fetch_assoc();

$stmt->close();

// ============================================================
// START TRANSACTION
// ============================================================

$conn->begin_transaction();

try {

    // ========================================================
    // ACTION 1:
    // RESPONSIBILITY REVIEW
    // ========================================================

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

        if ($updateId <= 0) {

            throw new Exception(
                "Valid update_id is required."
            );
        }

        // ====================================================
        // VERIFY UPDATE BELONGS TO EMPLOYEE
        // ====================================================

        $stmt = $conn->prepare("
            SELECT
                dru.id,
                dru.user_id,
                dru.responsibility_id,
                dru.report_date,
                dru.morning_checked,
                dru.evening_completed,
                dru.hits,
                dru.missed,
                dru.carry_forward,
                dru.employee_remarks,
                dru.manager_remarks,
                dru.status,
                dr.responsibility_title
            FROM daily_responsibility_updates dru

            INNER JOIN daily_responsibilities dr
                ON dr.id =
                    dru.responsibility_id

            WHERE dru.id = ?
              AND dru.user_id = ?
              AND dr.user_id = ?

            LIMIT 1
        ");

        if (!$stmt) {

            throw new Exception(
                "Unable to load responsibility update."
            );
        }

        $stmt->bind_param(
            "iii",
            $updateId,
            $employeeId,
            $employeeId
        );

        $stmt->execute();

        $result =
            $stmt->get_result();

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

            $stmt->close();

            throw new Exception(
                "Responsibility update not found for this employee."
            );
        }

        $responsibility =
            $result->fetch_assoc();

        $stmt->close();

        // ====================================================
        // MUST BE EVENING SUBMITTED
        // ====================================================

        if (
            (int)$responsibility[
                'evening_completed'
            ] !== 1
        ) {

            throw new Exception(
                "Employee has not submitted the evening responsibility update."
            );
        }

        // ====================================================
        // MANAGER REMARKS REQUIRED
        // ====================================================

        if ($managerRemarks === '') {

            throw new Exception(
                "Manager remarks are required."
            );
        }

        // ====================================================
        // UPDATE RESPONSIBILITY
        // ====================================================

        $stmt = $conn->prepare("
            UPDATE daily_responsibility_updates
            SET
                manager_remarks = ?,
                status = 'manager_reviewed'
            WHERE id = ?
              AND user_id = ?
        ");

        if (!$stmt) {

            throw new Exception(
                "Unable to prepare responsibility review."
            );
        }

        $stmt->bind_param(
            "sii",
            $managerRemarks,
            $updateId,
            $employeeId
        );

        if (!$stmt->execute()) {

            $stmt->close();

            throw new Exception(
                "Unable to save manager review."
            );
        }

        $stmt->close();

        $conn->commit();

        $conn->close();

        sendResponse(
            200,
            true,
            "Responsibility reviewed successfully.",
            [

                "action" =>
                    "responsibility_review",

                "manager" => [

                    "manager_id" =>
                        (string)$managerId,

                    "username" =>
                        $manager['username']
                ],

                "employee" => [

                    "employee_id" =>
                        (string)$employeeId,

                    "username" =>
                        $employee['username']
                ],

                "responsibility" => [

                    "update_id" =>
                        (string)$updateId,

                    "responsibility_id" =>
                        (string)$responsibility[
                            'responsibility_id'
                        ],

                    "title" =>
                        $responsibility[
                            'responsibility_title'
                        ],

                    "report_date" =>
                        $responsibility[
                            'report_date'
                        ],

                    "hits" =>
                        $responsibility['hits'],

                    "missed" =>
                        $responsibility['missed'],

                    "carry_forward" =>
                        $responsibility[
                            'carry_forward'
                        ],

                    "employee_remarks" =>
                        $responsibility[
                            'employee_remarks'
                        ],

                    "manager_remarks" =>
                        $managerRemarks,

                    "status" =>
                        "manager_reviewed"
                ]
            ]
        );
    }

    // ========================================================
    // ACTION 2 & 3:
    // KPI APPROVE / REJECT
    // ========================================================

    if (
        $action === 'kpi_approve' ||
        $action === 'kpi_reject'
    ) {

        if ($kpiActualId <= 0) {

            throw new Exception(
                "Valid kpi_actual_id is required."
            );
        }

        // ====================================================
        // GET KPI ACTUAL
        // ====================================================

        $stmt = $conn->prepare("
            SELECT
                id,
                user_id,
                kpi_id,
                month_key,
                week_start,
                week_end,
                actual_value,
                status,
                employee_comment,
                manager_comment,
                manager_approved
            FROM kpi_actuals
            WHERE id = ?
              AND user_id = ?
            LIMIT 1
        ");

        if (!$stmt) {

            throw new Exception(
                "Unable to load KPI actual."
            );
        }

        $stmt->bind_param(
            "ii",
            $kpiActualId,
            $employeeId
        );

        $stmt->execute();

        $result =
            $stmt->get_result();

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

            $stmt->close();

            throw new Exception(
                "KPI actual not found for this employee."
            );
        }

        $kpi =
            $result->fetch_assoc();

        $stmt->close();

        // ====================================================
        // HR VERIFIED CANNOT BE CHANGED
        // ====================================================

        if (
            $kpi['status'] ===
            'hr_verified'
        ) {

            throw new Exception(
                "This KPI has already been verified by HR and cannot be changed."
            );
        }

        // ====================================================
        // KPI APPROVE
        // ====================================================

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

            $stmt = $conn->prepare("
                UPDATE kpi_actuals
                SET
                    status =
                        'manager_approved',
                    manager_approved = 1,
                    manager_comment = ?,
                    approved_at = NOW()
                WHERE id = ?
                  AND user_id = ?
            ");

            if (!$stmt) {

                throw new Exception(
                    "Unable to prepare KPI approval."
                );
            }

            $stmt->bind_param(
                "sii",
                $managerComment,
                $kpiActualId,
                $employeeId
            );

            if (!$stmt->execute()) {

                $stmt->close();

                throw new Exception(
                    "Unable to approve KPI."
                );
            }

            $stmt->close();

            $finalStatus =
                'manager_approved';

            $message =
                'KPI approved successfully.';
        }

        // ====================================================
        // KPI REJECT
        // ====================================================

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

            if (
                $managerComment === ''
            ) {

                throw new Exception(
                    "Manager comment is required when rejecting a KPI."
                );
            }

            $stmt = $conn->prepare("
                UPDATE kpi_actuals
                SET
                    status = 'rejected',
                    manager_approved = 0,
                    manager_comment = ?,
                    approved_at = NULL
                WHERE id = ?
                  AND user_id = ?
            ");

            if (!$stmt) {

                throw new Exception(
                    "Unable to prepare KPI rejection."
                );
            }

            $stmt->bind_param(
                "sii",
                $managerComment,
                $kpiActualId,
                $employeeId
            );

            if (!$stmt->execute()) {

                $stmt->close();

                throw new Exception(
                    "Unable to reject KPI."
                );
            }

            $stmt->close();

            $finalStatus =
                'rejected';

            $message =
                'KPI rejected successfully.';
        }

        // ====================================================
        // COMMIT
        // ====================================================

        $conn->commit();

        $conn->close();

        sendResponse(
            200,
            true,
            $message,
            [

                "action" =>
                    $action,

                "manager" => [

                    "manager_id" =>
                        (string)$managerId,

                    "username" =>
                        $manager['username']
                ],

                "employee" => [

                    "employee_id" =>
                        (string)$employeeId,

                    "username" =>
                        $employee['username']
                ],

                "kpi" => [

                    "kpi_actual_id" =>
                        (string)$kpiActualId,

                    "kpi_id" =>
                        (string)$kpi['kpi_id'],

                    "month_key" =>
                        $kpi['month_key'],

                    "week_start" =>
                        $kpi['week_start'],

                    "week_end" =>
                        $kpi['week_end'],

                    "actual_value" =>
                        (float)$kpi[
                            'actual_value'
                        ],

                    "employee_comment" =>
                        $kpi[
                            'employee_comment'
                        ],

                    "manager_comment" =>
                        $managerComment,

                    "status" =>
                        $finalStatus
                ]
            ]
        );
    }

} catch (Throwable $e) {

    $conn->rollback();

    $conn->close();

    sendResponse(
        400,
        false,
        $e->getMessage()
    );
}

?>