<?php
require "../config/database.php";
require "../includes/auth.php";
require "../includes/csrf.php";

error_reporting(0);

header("Content-Type: application/json; charset=utf-8");
requireApiAuth();

$userId = (int)($_SESSION["user"]["id"] ?? 0);
$roleId = (int)($_SESSION["user"]["role_id"] ?? 0);
$method = $_SERVER["REQUEST_METHOD"] ?? "GET";

$allowedStatuses = ["pending", "approved", "rejected", "cancelled"];

if ($method === "POST") {
    $data = json_decode(file_get_contents("php://input"), true);
    if (!is_array($data)) {
        http_response_code(400);
        echo json_encode(["success" => false, "error" => "invalid_payload"]);
        exit;
    }

    if (!requireCsrfFromPayload($data, "csrf")) {
        http_response_code(403);
        echo json_encode(["success" => false, "error" => "invalid_csrf"]);
        exit;
    }

    if ($roleId !== 4) {
        http_response_code(403);
        echo json_encode(["success" => false, "error" => "only_company_can_request"]);
        exit;
    }

    $workerId = (int)($data["worker_id"] ?? 0);
    $message = trim((string)($data["message"] ?? ""));

    if ($workerId <= 0) {
        http_response_code(422);
        echo json_encode(["success" => false, "error" => "worker_required"]);
        exit;
    }

    $agencyId = 0;

    $workerOwnerStmt = $pdo->prepare("
        SELECT w.user_id, u.role_id
        FROM workers w
        LEFT JOIN users u ON u.id = w.user_id
        WHERE w.id = ?
        LIMIT 1
    ");
    $workerOwnerStmt->execute([$workerId]);
    $ownerRow = $workerOwnerStmt->fetch(PDO::FETCH_ASSOC);

    if (!$ownerRow) {
        http_response_code(404);
        echo json_encode(["success" => false, "error" => "worker_not_found"]);
        exit;
    }

    $ownerUserId = (int)($ownerRow["user_id"] ?? 0);
    $ownerRoleId = (int)($ownerRow["role_id"] ?? 0);

    if ($ownerUserId > 0 && $ownerRoleId === 3) {
        $agencyId = $ownerUserId;
    } else {
        $adminLookup = $pdo->prepare("
            SELECT id FROM users
            WHERE role_id = 1
            ORDER BY id ASC
            LIMIT 1
        ");
        $adminLookup->execute();
        $agencyId = (int)$adminLookup->fetchColumn();
    }

    if ($agencyId <= 0) {
        $selfFallback = $pdo->prepare("SELECT id FROM users WHERE id = ? LIMIT 1");
        $selfFallback->execute([$userId]);
        $agencyId = (int)$selfFallback->fetchColumn();
    }

    if ($agencyId <= 0) {
        http_response_code(422);
        echo json_encode(["success" => false, "error" => "agency_or_admin_required"]);
        exit;
    }

    $subStmt = $pdo->prepare("
        SELECT id, status, expires_at, monthly_request_limit, requests_used
        FROM company_subscriptions
        WHERE company_id = ?
        ORDER BY id DESC
        LIMIT 1
    ");
    $subStmt->execute([$userId]);
    $sub = $subStmt->fetch(PDO::FETCH_ASSOC);

    if (!$sub) {
        http_response_code(403);
        echo json_encode(["success" => false, "error" => "subscription_required"]);
        exit;
    }

    $subId = (int)($sub["id"] ?? 0);
    $subStatus = (string)($sub["status"] ?? "");
    $expiresAt = (string)($sub["expires_at"] ?? "");
    $requestLimit = (int)($sub["monthly_request_limit"] ?? 0);
    $requestsUsed = (int)($sub["requests_used"] ?? 0);

    if ($subStatus !== "active") {
        http_response_code(403);
        echo json_encode(["success" => false, "error" => "subscription_not_active"]);
        exit;
    }

    if ($expiresAt === "" || strtotime($expiresAt) === false || strtotime($expiresAt) < time()) {
        if ($subId > 0) {
            $expireStmt = $pdo->prepare("UPDATE company_subscriptions SET status = 'expired', updated_at = NOW() WHERE id = ?");
            $expireStmt->execute([$subId]);
        }
        http_response_code(403);
        echo json_encode(["success" => false, "error" => "subscription_expired"]);
        exit;
    }

    if ($requestLimit > 0 && $requestsUsed >= $requestLimit) {
        http_response_code(403);
        echo json_encode(["success" => false, "error" => "request_limit_reached"]);
        exit;
    }

    try {
        $pdo->beginTransaction();

        $stmt = $pdo->prepare("
            INSERT INTO requests (company_id, agency_id, worker_id, status, message, created_at, updated_at)
            VALUES (?, ?, ?, 'pending', ?, NOW(), NOW())
        ");
        $stmt->execute([$userId, $agencyId, $workerId, $message]);
        $requestId = (int)$pdo->lastInsertId();

        $usageUpdate = $pdo->prepare("
            UPDATE company_subscriptions
            SET requests_used = requests_used + 1, updated_at = NOW()
            WHERE id = ?
        ");
        $usageUpdate->execute([$subId]);

        $pdo->commit();

        echo json_encode([
            "success" => true,
            "request_id" => $requestId,
            "subscription_usage" => [
                "limit" => $requestLimit,
                "used" => $requestsUsed + 1,
                "remaining" => max(0, $requestLimit - ($requestsUsed + 1)),
                "expires_at" => $expiresAt
            ]
        ]);
        exit;
    } catch (Throwable $e) {
        if ($pdo->inTransaction()) {
            $pdo->rollBack();
        }
        http_response_code(500);
        $dbMsg = trim((string)$e->getMessage());
        if ($dbMsg === "") $dbMsg = "failed_to_create_request";
        echo json_encode(["success" => false, "error" => "failed_to_create_request", "detail" => $dbMsg]);
        exit;
    }
}

if ($method === "DELETE") {
    $data = json_decode(file_get_contents("php://input"), true);
    if (!is_array($data)) {
        http_response_code(400);
        echo json_encode(["success" => false, "error" => "invalid_payload"]);
        exit;
    }

    if (!requireCsrfFromPayload($data, "csrf")) {
        http_response_code(403);
        echo json_encode(["success" => false, "error" => "invalid_csrf"]);
        exit;
    }

    if ($roleId !== 1 && $roleId !== 5) {
        http_response_code(403);
        echo json_encode(["success" => false, "error" => "only_admin_or_moderator_can_delete_requests"]);
        exit;
    }

    $requestId = (int)($data["id"] ?? 0);
    if ($requestId <= 0) {
        http_response_code(422);
        echo json_encode(["success" => false, "error" => "invalid_request_id"]);
        exit;
    }

    $del = $pdo->prepare("DELETE FROM requests WHERE id = ?");
    $del->execute([$requestId]);

    echo json_encode(["success" => true]);
    exit;
}

if ($method === "PUT") {
    $data = json_decode(file_get_contents("php://input"), true);
    if (!is_array($data)) {
        http_response_code(400);
        echo json_encode(["success" => false, "error" => "invalid_payload"]);
        exit;
    }

    if (!requireCsrfFromPayload($data, "csrf")) {
        http_response_code(403);
        echo json_encode(["success" => false, "error" => "invalid_csrf"]);
        exit;
    }

    $requestId = (int)($data["id"] ?? 0);
    $status = trim((string)($data["status"] ?? ""));

    if ($requestId <= 0 || !in_array($status, $allowedStatuses, true)) {
        http_response_code(422);
        echo json_encode(["success" => false, "error" => "invalid_request_or_status"]);
        exit;
    }

    $stmt = $pdo->prepare("
        UPDATE requests
        SET status = ?, updated_at = NOW()
        WHERE id = ? AND (agency_id = ? OR company_id = ? OR ? = 1)
    ");
    $stmt->execute([$status, $requestId, $userId, $userId, $roleId]);

    echo json_encode(["success" => true]);
    exit;
}

$where = " WHERE (r.company_id = ? OR r.agency_id = ? OR ? = 1)";
$params = [$userId, $userId, $roleId];

$statusFilter = trim((string)($_GET["status"] ?? ""));
if ($statusFilter !== "") {
    if (!in_array($statusFilter, $allowedStatuses, true)) {
        http_response_code(422);
        echo json_encode(["success" => false, "error" => "invalid_status"]);
        exit;
    }
    $where .= " AND r.status = ?";
    $params[] = $statusFilter;
}

$stmt = $pdo->prepare("
    SELECT 
        r.id, r.company_id, r.agency_id, r.worker_id, r.status, r.message, r.created_at, r.updated_at,
        c.email AS company_email,
        a.email AS agency_email,
        w.first_name, w.last_name
    FROM requests r
    LEFT JOIN users c ON c.id = r.company_id
    LEFT JOIN users a ON a.id = r.agency_id
    LEFT JOIN workers w ON w.id = r.worker_id
    $where
    ORDER BY r.id DESC
");
$stmt->execute($params);

echo json_encode(["success" => true, "data" => $stmt->fetchAll(PDO::FETCH_ASSOC)]);
?>
