<?php
require_once plugin_dir_path(__FILE__) . '../controller/logger.php';
require_once plugin_dir_path(__FILE__) . '../model/olm-login.php';



function get_all_host_from_olm_cache()
{
    $olm_api = get_option('olm_url');
    $token_olm = cache_get_olm_token();
    $headers_olm = array(
        'Content-Type: application/json',
        'Accept: application/json',
        'Authorization: Bearer ' . $token_olm['bearerToken']
    );
    $page = 1;
    $size = 1000;
    $allResults = [];

    do {
        echo "page: $page<br>";
        flush();
        $url = $olm_api . "/api/rest/v1/host?page={$page}&size={$size}";
        $response = curl_get($url, $headers_olm);

        flush();
        $data = $response;

        flush();
        if ($data === null) {
            echo "Fehlgeschlagen beim Abrufen der Seite {$page}. Ungültiges JSON.<br>";
            throw new Exception("Ungültiges JSON auf Seite {$page}");
        }

        // Inhalte sammeln (falls vorhanden)
        if (isset($data['content']) && is_array($data['content'])) {
            $allResults = array_merge($allResults, $data['content']);
        }


        $isLast = $data['last'] ?? true; // Sicherheitshalber abbrechen, falls Feld fehlt
        $page++;


    } while ($isLast === false);



    global $wpdb;
    $table = $wpdb->prefix . 'api_cache';

    foreach ($allResults as $item) {


        flush();
        $json_id = $item['id'];
        $name = $item['name'];
        $customer_no = $item['customer']['customerNo'];
        $customer_name = $item['customer']['name'];
        $identifier = $item['identifier'];
        $reported_version = $item['reportedVersion'] ?? null;

        // Falls assignedReseller.customerNo existiert
        $assigned_reseller_no = $item['customer']['assignedReseller']['customerNo'] ?? null;

        $wpdb->replace(
            $table,
            [
                'json_id' => $json_id,
                'name' => $name,
                'customer_no' => $customer_no,
                'customer' => $customer_name,
                'identifier' => $identifier,
                'assigned_reseller_no' => $assigned_reseller_no,
                'reported_version' => $reported_version,
                'response' => json_encode($item),
            ]
        );

    }

}
function _host_build_where_sql($wpdb, $search, $filters)
{
    $filter_map = [
        'name'       => 'customer',
        'customerNo' => 'customer_no',
        'hostName'   => 'name',
        'licenseKey' => 'identifier',
    ];

    $search  = trim((string) $search);
    $pbx_key = strtolower(str_replace('-', '', $search));

    $where_parts    = [];
    $prepare_values = [];

    if ($search !== '') {
        if (!empty($filters)) {
            foreach ($filters as $filter) {
                if (!isset($filter_map[$filter])) continue;
                $column           = $filter_map[$filter];
                $where_parts[]    = "$column LIKE %s";
                $prepare_values[] = '%' . $wpdb->esc_like($column === 'identifier' ? $pbx_key : $search) . '%';
            }
        } else {
            $where_parts    = ["customer LIKE %s", "name LIKE %s", "customer_no LIKE %s", "identifier LIKE %s"];
            $prepare_values = [
                '%' . $wpdb->esc_like($search) . '%',
                '%' . $wpdb->esc_like($search) . '%',
                '%' . $wpdb->esc_like($search) . '%',
                '%' . $wpdb->esc_like($pbx_key) . '%',
            ];
        }
    }

    $where_sql = empty($where_parts) ? '' : ' AND (' . implode(' OR ', $where_parts) . ')';

    return [$where_sql, $prepare_values];
}

function host_db_reseller_cached($customer_no, $start, $size, $search, $filters = [])
{
    global $wpdb;
    $table = $wpdb->prefix . 'api_cache';
    $start = (int) $start;
    $size  = (int) $size;

    [$where_sql, $prepare_values] = _host_build_where_sql($wpdb, $search, $filters);

    $total_count = $wpdb->get_var($wpdb->prepare(
        "SELECT COUNT(*) FROM {$table}
         WHERE (customer_no = %s OR assigned_reseller_no = %s) {$where_sql}",
        array_merge([$customer_no, $customer_no], $prepare_values)
    ));

    $result = $wpdb->get_results($wpdb->prepare(
        "SELECT response FROM {$table}
         WHERE (customer_no = %s OR assigned_reseller_no = %s) {$where_sql}
         ORDER BY customer ASC LIMIT %d OFFSET %d",
        array_merge([$customer_no, $customer_no], $prepare_values, [$size, $start])
    ), ARRAY_A);

    foreach ($result as $item) {
        $entry = json_decode($item['response'], true);
        if ($uuid = $entry['id'] ?? null) queue_add_job('cachedKunden', $uuid);
    }

    return ['total' => (int) $total_count, 'data' => $result];
}

function host_db_reseller_cached_by_customer($customer_no, $page, $size, $search, $filters = [])
{
    global $wpdb;
    $table = $wpdb->prefix . 'api_cache';
    $start = (int) (($page - 1) * $size);
    $size  = (int) $size;

    [$where_sql, $prepare_values] = _host_build_where_sql($wpdb, $search, $filters);

    $total_count = $wpdb->get_var($wpdb->prepare(
        "SELECT COUNT(DISTINCT customer_no) FROM {$table}
         WHERE (customer_no = %s OR assigned_reseller_no = %s) {$where_sql}",
        array_merge([$customer_no, $customer_no], $prepare_values)
    ));

    $customer_nos = $wpdb->get_col($wpdb->prepare(
        "SELECT DISTINCT customer_no FROM {$table}
         WHERE (customer_no = %s OR assigned_reseller_no = %s) {$where_sql}
         ORDER BY customer ASC LIMIT %d OFFSET %d",
        array_merge([$customer_no, $customer_no], $prepare_values, [$size, $start])
    ));

    if (empty($customer_nos)) {
        return ['total' => (int) $total_count, 'data' => []];
    }

    $placeholders = implode(',', array_fill(0, count($customer_nos), '%s'));
    $result = $wpdb->get_results($wpdb->prepare(
        "SELECT response FROM {$table}
         WHERE customer_no IN ($placeholders)
         AND (customer_no = %s OR assigned_reseller_no = %s)
         ORDER BY customer ASC, name ASC",
        array_merge($customer_nos, [$customer_no, $customer_no])
    ), ARRAY_A);

    foreach ($result as $item) {
        $entry = json_decode($item['response'], true);
        if ($uuid = $entry['id'] ?? null) queue_add_job('cachedKunden', $uuid);
    }

    return ['total' => (int) $total_count, 'data' => $result];
}

function refresh_host_by($id)
{

    $url = get_option('olm_url') . "/api/rest/v1/host/{$id}";
    $token_olm = cache_get_olm_token();
    $headers_olm = array(
        'Content-Type: application/json',
        'Accept: application/json',
        'Authorization: Bearer ' . $token_olm['bearerToken']
    );
    $item = curl_get($url, $headers_olm);


    $json_id = $item['id'];
    $name = $item['name'];
    $customer_no = $item['customer']['customerNo'];
    $customer_name = $item['customer']['name'];
    $identifier = $item['identifier'];
    $reported_version = $item['reportedVersion'] ?? null;

    // Falls assignedReseller.customerNo existiert
    $assigned_reseller_no = $item['customer']['assignedReseller']['customerNo'] ?? null;


    global $wpdb;
    $table = $wpdb->prefix . 'api_cache';

    $wpdb->replace(
        $table,
        [
            'json_id' => $json_id,
            'name' => $name,
            'customer_no' => $customer_no,
            'customer' => $customer_name,
            'identifier' => $identifier,
            'assigned_reseller_no' => $assigned_reseller_no,
            'reported_version' => $reported_version,
            'response' => json_encode($item),
        ]
    );


}

function curl_get($url, $headers)
{
    $maxRetries = 3;
    $attempt = 0;
    $response = false;
    $start = microtime(true);

    $formattedHeaders = [];
    foreach ($headers as $key => $value) {
        $formattedHeaders[] = $key . ": " . $value;
    }

    do {
        $opts = [
            "http" => [
                "method" => "GET",
                "header" => $headers,
                "timeout" => 3, // Timeout in Sekunden
            ]

            // ,
            // "ssl" => [
            //     "verify_peer"      => false, // wie CURLOPT_SSL_VERIFYPEER
            //     "verify_peer_name" => false, // wie CURLOPT_SSL_VERIFYHOST
            // ]
        ];

        $context = stream_context_create($opts);
        $response = @file_get_contents($url, false, $context);
        $attempt++;

        if ($response === false) {
            $error = error_get_last();
            log_msg("Versuch $attempt fehlgeschlagen: " . ($error['message'] ?? 'Unbekannter Fehler') . " url: $url<br>");
            flush();
        }

    } while ($response === false && $attempt < $maxRetries);

    if ($response === false) {
        echo "Fehler nach $maxRetries Versuchen: ";
        log_msg("❌ ERROR: CURL GET fehlgeschlagen nach $maxRetries Versuchen: " . ($error['message'] ?? 'Unbekannter Fehler') . " url: $url<br>");
        return null;
    }

    return json_decode($response, true);
}

function curl_get_cached($url, $headers, $norefresh = true)
{

    $hash = md5($url);
    $kundennummer = explode('/', trim((explode('/api/rest/v1/customer/customerno/', $url)[1]), '/'))[0];
    $cached = get_transient($hash);


    if (!$norefresh) {

        $response = curl_get($url, $headers);
        delete_transient($hash);

        $result = set_transient($hash, $response, 7200 * MINUTE_IN_SECONDS);
        if (!$result) {
            log_msg("❌ Transient konnte nicht gesetzt werden!");

        }
        return null;
    }

    if (!($cached === false)) {

        queue_add_job('cachedKunden', $kundennummer);
        return $cached; // aus Cache
    }

    $response = curl_get($url, $headers);
    set_transient($hash, $response, 7200 * MINUTE_IN_SECONDS);

    return $response;
}





function post_request($url, $headers, $data)
{
    $options = array(
        'http' => array(
            'header' => implode("\r\n", $headers),
            'method' => 'POST',
            'content' => json_encode($data)
        )
    );
    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);
    return json_decode($result, true);
}




function queue_add_job($job_type, $payload = [])
{
    global $wpdb;

    $table = $wpdb->prefix . "job_queue";



    // Prüfen ob Payload existiert
    $exists = $wpdb->get_var(
        $wpdb->prepare(
            "SELECT 1 FROM {$table} WHERE payload = %s LIMIT 1",
            $payload
        )
    );

    if ($exists) {
        return false; // oder true / ID zurückgeben – je nach Logik
    }



    $wpdb->insert(
        $table,
        [
            'job_type' => sanitize_text_field($job_type),
            'payload' => ($payload),
            'status' => 'pending',
            'created_at' => current_time('mysql'),
        ]
    );

    return $wpdb->insert_id; // Job-ID zurückgeben
}



?>