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

error_reporting(E_ALL);
ini_set("display_errors", "0");
header("Content-Type: application/json; charset=utf-8");

function respondSuccess(array $extra = []): void
{
    echo json_encode(array_merge(["status" => "success"], $extra));
    exit;
}

function respondError(string $message, int $http = 400, ?Throwable $e = null): void
{
    http_response_code($http);
    if ($e !== null) {
        error_log("[profile_update.php] {$message}: " . $e->getMessage());
    } else {
        error_log("[profile_update.php] {$message}");
    }
    echo json_encode([
        "status" => "error",
        "message" => $message
    ]);
    exit;
}

function hasColumn(PDO $pdo, string $table, string $column): bool
{
    static $cache = [];
    $key = $table . "." . $column;
    if (isset($cache[$key])) {
        return $cache[$key];
    }

    try {
        $stmt = $pdo->prepare("
            SELECT COUNT(*)
            FROM INFORMATION_SCHEMA.COLUMNS
            WHERE TABLE_SCHEMA = DATABASE()
              AND TABLE_NAME = ?
              AND COLUMN_NAME = ?
        ");
        $stmt->execute([$table, $column]);
        $cache[$key] = ((int)$stmt->fetchColumn() > 0);
        return $cache[$key];
    } catch (Throwable $e) {
        error_log("[profile_update.php] hasColumn failed for {$key}: " . $e->getMessage());
        $cache[$key] = false;
        return false;
    }
}

function availableProfileColumns(PDO $pdo): array
{
    $possible = [
        "agency_name", "agency_address", "agency_contact", "agency_tax_id",
        "company_name", "company_address", "company_contact", "company_tax_id",
        "skills", "languages", "country", "availability", "certificates", "cv_url",
        "location", "bio", "photo_url", "youtube_url", "video_interview", "video_work",
        "desired_salary_from", "desired_salary_to"
    ];

    $cols = [];
    foreach ($possible as $col) {
        if (hasColumn($pdo, "user_profiles", $col)) {
            $cols[] = $col;
        }
    }
    return $cols;
}

function normalizeProfileForRole(array $row, int $roleId): array
{
    $base = [
        "agency_name" => (string)($row["agency_name"] ?? ""),
        "agency_address" => (string)($row["agency_address"] ?? ""),
        "agency_contact" => (string)($row["agency_contact"] ?? ""),
        "agency_tax_id" => (string)($row["agency_tax_id"] ?? ""),
        "company_name" => (string)($row["company_name"] ?? ""),
        "company_address" => (string)($row["company_address"] ?? ""),
        "company_contact" => (string)($row["company_contact"] ?? ""),
        "company_tax_id" => (string)($row["company_tax_id"] ?? ""),
        "skills" => (string)($row["skills"] ?? ""),
        "languages" => (string)($row["languages"] ?? ""),
        "country" => (string)($row["country"] ?? ""),
        "availability" => (string)($row["availability"] ?? ""),
        "certificates" => (string)($row["certificates"] ?? ""),
        "cv_url" => (string)($row["cv_url"] ?? ""),
        "location" => (string)($row["location"] ?? ""),
        "bio" => (string)($row["bio"] ?? ""),
        "photo_url" => (string)($row["photo_url"] ?? ""),
        "youtube_url" => (string)($row["youtube_url"] ?? ""),
        "video_interview" => (string)($row["video_interview"] ?? ""),
        "video_work" => (string)($row["video_work"] ?? ""),
        "desired_salary_from" => (string)($row["desired_salary_from"] ?? ""),
        "desired_salary_to" => (string)($row["desired_salary_to"] ?? "")
    ];

    if ($roleId === 3) {
        $base["skills"] = "";
        $base["youtube_url"] = "";
        $base["video_interview"] = "";
        $base["video_work"] = "";
        $base["cv_url"] = "";
        $base["availability"] = "";
        $base["certificates"] = "";
        $base["desired_salary_from"] = "";
        $base["desired_salary_to"] = "";
    } elseif ($roleId === 4) {
        $base["skills"] = "";
        $base["youtube_url"] = "";
        $base["video_interview"] = "";
        $base["video_work"] = "";
        $base["cv_url"] = "";
        $base["availability"] = "";
        $base["certificates"] = "";
        $base["agency_name"] = "";
        $base["agency_address"] = "";
        $base["agency_contact"] = "";
        $base["agency_tax_id"] = "";
        $base["desired_salary_from"] = "";
        $base["desired_salary_to"] = "";
    } elseif ($roleId !== 2) {
        $base["desired_salary_from"] = "";
        $base["desired_salary_to"] = "";
    }

    return $base;
}

try {
    if (!isset($pdo) || !($pdo instanceof PDO)) {
        respondError("database_not_initialized", 500);
    }

    requireApiAuth();

    $authUserId = (int)($_SESSION["user"]["id"] ?? 0);
    $roleId = (int)($_SESSION["user"]["role_id"] ?? 0);
    if ($authUserId <= 0) {
        respondError("unauthorized", 401);
    }

    $canEditOthers = ($roleId === 1 || $roleId === 5);
    $method = $_SERVER["REQUEST_METHOD"] ?? "GET";

    if ($method === "GET") {
        $targetUserId = $authUserId;
        $rawUserId = $_GET["user_id"] ?? "self";

        if ($rawUserId !== "self" && $rawUserId !== "" && $rawUserId !== null) {
            $targetUserId = (int)$rawUserId;
        }

        $workerId = (int)($_GET["worker_id"] ?? 0);
        if ($workerId > 0) {
            $wStmt = $pdo->prepare("SELECT user_id FROM workers WHERE id = ? LIMIT 1");
            $wStmt->execute([$workerId]);
            $resolvedUserId = (int)($wStmt->fetchColumn() ?: 0);
            if ($resolvedUserId > 0) {
                $targetUserId = $resolvedUserId;
            }
        }

        if ($targetUserId <= 0) {
            $targetUserId = $authUserId;
        }

        $targetRoleId = $roleId;
        $roleStmt = $pdo->prepare("SELECT role_id FROM users WHERE id = ? LIMIT 1");
        $roleStmt->execute([$targetUserId]);
        $dbRole = (int)($roleStmt->fetchColumn() ?: 0);
        if ($dbRole > 0) {
            $targetRoleId = $dbRole;
        }

        $stmt = $pdo->prepare("SELECT * FROM user_profiles WHERE user_id = ? LIMIT 1");
        $stmt->execute([$targetUserId]);
        $profile = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!is_array($profile)) {
            $profile = [];
        }

        $userStmt = $pdo->prepare("
            SELECT agency_name, agency_address, agency_tax_id, company_name, company_address, company_tax_id
            FROM users
            WHERE id = ?
            LIMIT 1
        ");
        $userStmt->execute([$targetUserId]);
        $uRow = $userStmt->fetch(PDO::FETCH_ASSOC) ?: [];

        if ($targetRoleId === 3) {
            $profile["agency_name"] = (string)($uRow["agency_name"] ?? ($profile["agency_name"] ?? ""));
            $profile["agency_address"] = (string)($uRow["agency_address"] ?? ($profile["agency_address"] ?? ""));
            $profile["agency_tax_id"] = (string)($uRow["agency_tax_id"] ?? ($profile["agency_tax_id"] ?? ""));
        } elseif ($targetRoleId === 4) {
            $profile["company_name"] = (string)($uRow["company_name"] ?? ($profile["company_name"] ?? ""));
            $profile["company_address"] = (string)($uRow["company_address"] ?? ($profile["company_address"] ?? ""));
            $profile["company_tax_id"] = (string)($uRow["company_tax_id"] ?? ($profile["company_tax_id"] ?? ""));
        }

        respondSuccess([
            "data" => normalizeProfileForRole($profile, $targetRoleId),
            "role_id" => $targetRoleId
        ]);
    }

    if ($method !== "POST") {
        respondError("method_not_allowed", 405);
    }

    $input = $_POST;
    if (!is_array($input) || count($input) === 0) {
        $rawBody = file_get_contents("php://input");
        $decoded = json_decode($rawBody, true);
        if (is_array($decoded)) {
            $input = $decoded;
        }
    }

    if (!is_array($input) || count($input) === 0) {
        respondError("invalid_payload", 400);
    }

    if (!requireCsrfFromPayload($input, "csrf")) {
        respondError("invalid_csrf", 403);
    }

    $targetUserId = $authUserId;
    $rawTargetUserId = $input["user_id"] ?? "self";
    if ($rawTargetUserId !== "self" && $rawTargetUserId !== "" && $rawTargetUserId !== null) {
        $targetUserId = (int)$rawTargetUserId;
    }
    $workerTargetId = (int)($input["worker_id"] ?? 0);
    if ($workerTargetId > 0) {
        $wStmt = $pdo->prepare("SELECT user_id FROM workers WHERE id = ? LIMIT 1");
        $wStmt->execute([$workerTargetId]);
        $resolvedUserId = (int)($wStmt->fetchColumn() ?: 0);
        if ($resolvedUserId > 0) {
            $targetUserId = $resolvedUserId;
        }
    }
    if ($targetUserId <= 0) {
        $targetUserId = $authUserId;
    }
    if ($targetUserId !== $authUserId && !$canEditOthers) {
        respondError("forbidden", 403);
    }

    $targetRoleId = $roleId;
    $targetRoleStmt = $pdo->prepare("SELECT role_id FROM users WHERE id = ? LIMIT 1");
    $targetRoleStmt->execute([$targetUserId]);
    $targetRoleFromDb = (int)($targetRoleStmt->fetchColumn() ?: 0);
    if ($targetRoleFromDb > 0) {
        $targetRoleId = $targetRoleFromDb;
    }

    $values = [
        "agency_name" => trim((string)($input["agency_name"] ?? "")),
        "agency_address" => trim((string)($input["agency_address"] ?? "")),
        "agency_contact" => trim((string)($input["agency_contact"] ?? "")),
        "agency_tax_id" => trim((string)($input["agency_tax_id"] ?? "")),
        "company_name" => trim((string)($input["company_name"] ?? "")),
        "company_address" => trim((string)($input["company_address"] ?? "")),
        "company_contact" => trim((string)($input["company_contact"] ?? "")),
        "company_tax_id" => trim((string)($input["company_tax_id"] ?? "")),
        "skills" => trim((string)($input["skills"] ?? "")),
        "languages" => trim((string)($input["languages"] ?? "")),
        "country" => trim((string)($input["country"] ?? "")),
        "availability" => trim((string)($input["availability"] ?? "")),
        "certificates" => trim((string)($input["certificates"] ?? "")),
        "cv_url" => trim((string)($input["cv_url"] ?? "")),
        "location" => trim((string)($input["location"] ?? "")),
        "bio" => trim((string)($input["bio"] ?? "")),
        "photo_url" => trim((string)($input["photo_url"] ?? "")),
        "youtube_url" => trim((string)($input["youtube_url"] ?? "")),
        "video_interview" => trim((string)($input["video_interview"] ?? "")),
        "video_work" => trim((string)($input["video_work"] ?? "")),
        "desired_salary_from" => null,
        "desired_salary_to" => null
    ];

    if ($values["photo_url"] !== "" && !filter_var($values["photo_url"], FILTER_VALIDATE_URL)) {
        respondError("invalid_photo_url", 422);
    }
    if ($values["youtube_url"] !== "" && !filter_var($values["youtube_url"], FILTER_VALIDATE_URL)) {
        respondError("invalid_youtube_url", 422);
    }
    if ($values["cv_url"] !== "" && !filter_var($values["cv_url"], FILTER_VALIDATE_URL)) {
        respondError("invalid_cv_url", 422);
    }
    if ($values["video_interview"] !== "" && !filter_var($values["video_interview"], FILTER_VALIDATE_URL)) {
        respondError("invalid_video_interview_url", 422);
    }
    if ($values["video_work"] !== "" && !filter_var($values["video_work"], FILTER_VALIDATE_URL)) {
        respondError("invalid_video_work_url", 422);
    }

    $salaryFromRaw = trim((string)($input["desired_salary_from"] ?? ""));
    $salaryToRaw = trim((string)($input["desired_salary_to"] ?? ""));

    if ($salaryFromRaw !== "") {
        if (!preg_match('/^\d+$/', $salaryFromRaw)) {
            respondError("invalid_desired_salary_from", 422);
        }
        $values["desired_salary_from"] = (int)$salaryFromRaw;
    }

    if ($salaryToRaw !== "") {
        if (!preg_match('/^\d+$/', $salaryToRaw)) {
            respondError("invalid_desired_salary_to", 422);
        }
        $values["desired_salary_to"] = (int)$salaryToRaw;
    }

    if ($values["desired_salary_from"] !== null && $values["desired_salary_to"] !== null
        && $values["desired_salary_from"] > $values["desired_salary_to"]) {
        respondError("invalid_desired_salary_range", 422);
    }

    if ($targetRoleId === 3) {
        $values["skills"] = "";
        $values["youtube_url"] = "";
        $values["video_interview"] = "";
        $values["video_work"] = "";
        $values["cv_url"] = "";
        $values["availability"] = "";
        $values["certificates"] = "";
        $values["company_name"] = "";
        $values["company_address"] = "";
        $values["company_contact"] = "";
        $values["company_tax_id"] = "";
        $values["desired_salary_from"] = null;
        $values["desired_salary_to"] = null;
    } elseif ($targetRoleId === 4) {
        $values["skills"] = "";
        $values["youtube_url"] = "";
        $values["video_interview"] = "";
        $values["video_work"] = "";
        $values["cv_url"] = "";
        $values["availability"] = "";
        $values["certificates"] = "";
        $values["agency_name"] = "";
        $values["agency_address"] = "";
        $values["agency_contact"] = "";
        $values["agency_tax_id"] = "";
        $values["desired_salary_from"] = null;
        $values["desired_salary_to"] = null;
    } elseif ($targetRoleId !== 2) {
        $values["desired_salary_from"] = null;
        $values["desired_salary_to"] = null;
    }

    $columns = availableProfileColumns($pdo);
    if (empty($columns)) {
        respondError("profile_columns_missing", 500);
    }

    $existsStmt = $pdo->prepare("SELECT id FROM user_profiles WHERE user_id = ? LIMIT 1");
    $existsStmt->execute([$targetUserId]);
    $profileId = (int)($existsStmt->fetchColumn() ?: 0);

    if ($profileId > 0) {
        $setParts = [];
        $params = [];
        foreach ($columns as $col) {
            $setParts[] = "{$col} = ?";
            $params[] = $values[$col] ?? "";
        }
        if (hasColumn($pdo, "user_profiles", "updated_at")) {
            $setParts[] = "updated_at = NOW()";
        }
        $params[] = $targetUserId;

        $sql = "UPDATE user_profiles SET " . implode(", ", $setParts) . " WHERE user_id = ?";
        $stmt = $pdo->prepare($sql);
        $stmt->execute($params);
    } else {
        $insertCols = array_merge(["user_id"], $columns);
        $placeholders = implode(", ", array_fill(0, count($insertCols), "?"));
        $params = [$targetUserId];
        foreach ($columns as $col) {
            $params[] = $values[$col] ?? "";
        }

        $extraCols = [];
        $extraVals = [];
        if (hasColumn($pdo, "user_profiles", "created_at")) {
            $extraCols[] = "created_at";
            $extraVals[] = "NOW()";
        }
        if (hasColumn($pdo, "user_profiles", "updated_at")) {
            $extraCols[] = "updated_at";
            $extraVals[] = "NOW()";
        }

        $allColsSql = implode(", ", array_merge($insertCols, $extraCols));
        $allValsSql = $placeholders;
        if (!empty($extraVals)) {
            $allValsSql .= ", " . implode(", ", $extraVals);
        }

        $sql = "INSERT INTO user_profiles ({$allColsSql}) VALUES ({$allValsSql})";
        $stmt = $pdo->prepare($sql);
        $stmt->execute($params);
    }

    if ($targetRoleId === 3) {
        $updUserAgency = $pdo->prepare("
            UPDATE users
            SET agency_name = ?, agency_address = ?, agency_tax_id = ?, updated_at = NOW()
            WHERE id = ?
        ");
        $updUserAgency->execute([
            $values["agency_name"],
            $values["location"] !== "" ? $values["location"] : $values["agency_address"],
            $values["agency_tax_id"],
            $targetUserId
        ]);
    } elseif ($targetRoleId === 4) {
        $updUserCompany = $pdo->prepare("
            UPDATE users
            SET company_name = ?, company_address = ?, company_tax_id = ?, updated_at = NOW()
            WHERE id = ?
        ");
        $updUserCompany->execute([
            $values["company_name"],
            $values["location"] !== "" ? $values["location"] : $values["company_address"],
            $values["company_tax_id"],
            $targetUserId
        ]);
    }

    respondSuccess();
} catch (Throwable $e) {
    respondError("profile_update_failed", 500, $e);
}
