<?php
// [v2.15] api.php - Point d'entree UNIQUE et 100% AUTONOME
// - FIX CRITIQUE: CURLOPT_IPRESOLVE_V4 sur tous les curl
//   (o2switch: IPv6 cassé -> "Could not resolve host")
// - Host CRM FORCE + AUTO-CORRECTION (rest.CRM.com)
// - customField envoye comme TABLEAU [{id, value}]
// - action get_contact pour verification
// - $is_create restaure
// - health affiche le host utilise (diagnostic)
if (function_exists('opcache_reset')) { @opcache_reset(); }
error_reporting(0);
ini_set('display_errors', '0');

function send_cors() {
    $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '*';
    header("Access-Control-Allow-Origin: $origin");
    header("Access-Control-Allow-Credentials: true");
    header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
    header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, Accept, Origin, X-Api-Key, x-api-key");
}
send_cors();

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

function json_response($data, $code = 200) {
    http_response_code($code);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

function cfg() {
    static $c = null;
    if ($c === null) {
        $f = __DIR__ . '/config.php';
        if (file_exists($f)) {
            $c = require $f;
        } else {
            $c = array(
                'db_host'          => 'localhost',
                'db_port'          => 3306,
                'db_name'          => 'shha6455_chipoutsbox',
                'db_user'          => 'shha6455_shmuel',
                'db_pass'          => '682208HShs',
                'db_charset'       => 'utf8mb4',
                'api_key'          => 'cbx_9f3a7e2d1b4c8f6a0d5e2b7c9f1a3d8e_2026',
                'crm_api_key'      => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2NhdGlvbl9pZCI6IlduU3FjT0tac2ppZGhlZ25waFE5IiwidmVyc2lvbiI6MSwiaWF0IjoxNzg5MDM1NTk1MDk5LCJzdWIiOiJWWHI0YVhkUHlSOWp0NWdPUWRBTyJ9.ShaUdlXvFhvjRr-AgL0JlG8h7FMcJSlu7pZaVbH4mHs',
                'crm_api_host'     => 'rest.CRM.com',
                'crm_location_id'  => 'WnSqcOKZsjidhegnphQ9',
                'admin_code'       => '682208',
            );
        }
    }
    return $c;
}

function db() {
    static $pdo = null;
    if ($pdo === null) {
        $c = cfg();
        $dsn = "mysql:host={$c['db_host']};port={$c['db_port']};dbname={$c['db_name']};charset={$c['db_charset']}";
        $pdo = new PDO($dsn, $c['db_user'], $c['db_pass'], array(
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => false,
        ));
    }
    return $pdo;
}

function get_auth_token() {
    $hdr = isset($_SERVER['HTTP_AUTHORIZATION']) ? $_SERVER['HTTP_AUTHORIZATION'] : (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) ? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] : '');
    if (preg_match('/Bearer\s+(.+)/i', $hdr, $m)) return trim($m[1]);
    return isset($_GET['api_key']) ? $_GET['api_key'] : '';
}

function check_api_key() {
    $c = cfg();
    $tk = get_auth_token();
    $headers = function_exists('getallheaders') ? array_change_key_case(getallheaders(), CASE_LOWER) : array();
    $hk = isset($headers['x-api-key']) ? $headers['x-api-key'] : '';
    if ($tk !== $c['api_key'] && $hk !== $c['api_key']) {
        json_response(array('ok' => false, 'error' => 'Non autorise'), 401);
    }
}

function get_payload() {
    $raw = file_get_contents('php://input');
    if ($raw) {
        $j = json_decode($raw, true);
        if (is_array($j)) return $j;
    }
    if (isset($_GET['data'])) {
        $j = json_decode($_GET['data'], true);
        if (is_array($j)) return $j;
    }
    return $_POST;
}

$resource = isset($_GET['resource']) ? $_GET['resource'] : '';
$method   = $_SERVER['REQUEST_METHOD'];

// --- health ---
if ($method === 'GET' && $resource === 'health') {
    $c = cfg();
    $h = $c['crm_api_host'];
    if (strpos($h, 'CRM') === false) { $h = 'rest.CRM.com'; }
    json_response(array('ok' => true, 'time' => time(), 'php' => PHP_VERSION, 'ver' => 'v2.15-ipv4-fix', 'host' => $h, 'deploy' => '2026-09-13T00:00:00Z'), 200);
}

// --- ROUTE UNIFIEE: push / test_tag / crm_sync / crm_field ---
$unified = array('push', 'test_tag', 'crm_sync', 'crm_field');
if (in_array($resource, $unified, true)) {
    $c = cfg();
    $apiKey   = $c['crm_api_key'];
    $apiHost  = $c['crm_api_host'];
    // AUTO-CORRECTION: si le host n'est pas CRM, on force la bonne valeur
    if (strpos($apiHost, 'CRM') === false) {
        $apiHost = 'rest.CRM.com';
    }
    $location = $c['crm_location_id'];
    $b        = get_payload();

    $rawPhone   = isset($b['phone']) ? $b['phone'] : (isset($_GET['phone']) ? $_GET['phone'] : '');
    $rawEmail   = isset($b['email']) ? $b['email'] : (isset($_GET['email']) ? $_GET['email'] : '');
    $fieldsArr  = isset($b['fields']) ? $b['fields'] : (isset($_GET['fields']) ? json_decode($_GET['fields'], true) : null);
    $contactStd = isset($b['contact']) ? $b['contact'] : (isset($_GET['contact']) ? json_decode($_GET['contact'], true) : null);
    $tag        = isset($b['tag']) ? $b['tag'] : (isset($_GET['tag']) ? $_GET['tag'] : 'inscription forcer chipoutsbox');
    $action     = isset($b['action']) ? $b['action'] : (isset($_GET['action']) ? $_GET['action'] : 'fields_only');

    $digits = preg_replace('/[^0-9]/', '', (string)$rawPhone);
    $phoneN = '';
    if ($digits !== '') {
        $phoneN = (substr($digits, 0, 1) === '0') ? '+972' . substr($digits, 1) : '+' . $digits;
    }
    $emailClean = trim((string)$rawEmail);
    if ($phoneN === '' && $emailClean === '') {
        json_response(array('ok' => false, 'error' => 'phone ou email requis'), 400);
    }
    $out = array('phone' => $phoneN, 'email' => $emailClean, 'tag' => $tag, 'action' => $action, 'host' => $apiHost, 'has_key' => ($apiKey !== ''), 'ver' => 'v2.15-ipv4-fix', 'steps' => array());

    if ($apiKey === '') {
        $out['ok'] = false;
        $out['error'] = 'crm_api_key vide';
        json_response($out, 500);
    }

    if ($phoneN !== '') {
        $lookupUrl = "https://$apiHost/v1/contacts/lookup?locationId=" . urlencode($location) . "&phone=" . urlencode($phoneN);
    } else {
        $lookupUrl = "https://$apiHost/v1/contacts/lookup?locationId=" . urlencode($location) . "&email=" . urlencode($emailClean);
    }
    $ch1 = curl_init($lookupUrl);
    curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch1, CURLOPT_TIMEOUT, 20);
    curl_setopt($ch1, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
    curl_setopt($ch1, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $apiKey, 'Accept: application/json', 'Version: 2021-07-28'));
    $raw1  = curl_exec($ch1);
    $code1 = curl_getinfo($ch1, CURLINFO_HTTP_CODE);
    $err1  = curl_error($ch1);
    curl_close($ch1);
    $out['steps']['lookup'] = array('http' => $code1, 'err' => $err1, 'body' => substr((string)$raw1, 0, 30000));

    $data1 = json_decode((string)$raw1, true);
    $contacts = isset($data1['contacts']) ? $data1['contacts'] : array();
    if (empty($contacts)) {
        $out['ok'] = false;
        $out['error'] = 'Aucun contact pour ' . ($phoneN !== '' ? $phoneN : $emailClean);
        json_response($out, 404);
    }
    $cid = isset($contacts[0]['id']) ? $contacts[0]['id'] : '';
    $out['contact_id'] = $cid;

    $putBody = array();
    if (is_array($fieldsArr) && !empty($fieldsArr)) {
        $cfArr = array();
        foreach ($fieldsArr as $fid => $fval) {
            $cfArr[] = array('id' => $fid, 'value' => $fval);
        }
        $putBody['customField'] = $cfArr;
    }
    if (is_array($contactStd) && !empty($contactStd)) {
        foreach (array('firstName','lastName','name','email','phone','companyName','company') as $sk) {
            if (isset($contactStd[$sk]) && $contactStd[$sk] !== '') {
                $putBody[$sk] = $contactStd[$sk];
            }
        }
    }
    if (!empty($putBody)) {
        $ch2 = curl_init("https://$apiHost/v1/contacts/$cid");
        curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch2, CURLOPT_TIMEOUT, 20);
        curl_setopt($ch2, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
        curl_setopt($ch2, CURLOPT_CUSTOMREQUEST, 'PUT');
        curl_setopt($ch2, CURLOPT_POSTFIELDS, json_encode($putBody, JSON_UNESCAPED_UNICODE));
        curl_setopt($ch2, CURLOPT_HTTPHEADER, array(
            'Authorization: Bearer ' . $apiKey,
            'Accept: application/json',
            'Content-Type: application/json; charset=utf-8',
            'Version: 2021-07-28',
        ));
        $raw2  = curl_exec($ch2);
        $code2 = curl_getinfo($ch2, CURLINFO_HTTP_CODE);
        $err2  = curl_error($ch2);
        curl_close($ch2);
        $out['steps']['put_fields'] = array('http' => $code2, 'err' => $err2, 'fields' => array_keys($fieldsArr ?: array()), 'contact_keys' => array_keys($contactStd ?: array()), 'body' => substr((string)$raw2, 0, 3000));
    }

    if ($action === 'get_contact') {
        $out['contact_full'] = $raw1;
        $out['ok'] = true;
        json_response($out, 200);
    }

    if ($action !== 'fields_only') {
        $ch3 = curl_init("https://$apiHost/v1/contacts/$cid/tags");
        curl_setopt($ch3, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch3, CURLOPT_TIMEOUT, 20);
        curl_setopt($ch3, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
        curl_setopt($ch3, CURLOPT_CUSTOMREQUEST, ($action === 'add') ? 'POST' : 'DELETE');
        curl_setopt($ch3, CURLOPT_POSTFIELDS, json_encode(array('tags' => array($tag))));
        curl_setopt($ch3, CURLOPT_HTTPHEADER, array(
            'Authorization: Bearer ' . $apiKey,
            'Accept: application/json',
            'Content-Type: application/json',
            'Version: 2021-07-28',
        ));
        $raw3  = curl_exec($ch3);
        $code3 = curl_getinfo($ch3, CURLINFO_HTTP_CODE);
        $err3  = curl_error($ch3);
        curl_close($ch3);
        $out['steps'][$action . '_tag'] = array('http' => $code3, 'err' => $err3, 'body' => substr((string)$raw3, 0, 500));
        $out['ok'] = ($code3 >= 200 && $code3 < 300);
    } else {
        $out['ok'] = true;
    }
    json_response($out, 200);
}

// --- install ---
if ($method === 'GET' && $resource === 'install') {
    $f = __DIR__ . '/api_install.php';
    if (file_exists($f)) { require $f; exit; }
}

// --- upload ---
if ($resource === 'upload' && ($method === 'GET' || $method === 'POST')) {
    $f = __DIR__ . '/api_upload.php';
    if (file_exists($f)) { require $f; exit; }
}

check_api_key();

try {
    $action        = isset($_GET['action']) ? $_GET['action'] : '';
    $update_action = isset($_GET['update_action']) ? $_GET['update_action'] : '';
    $is_create     = ($method === 'POST') || ($method === 'GET' && $action === 'create');
    $b             = get_payload();

    $dispatchFile = __DIR__ . '/api_dispatches.php';
    $acceptFile   = __DIR__ . '/api_accept.php';
    $crudFile     = __DIR__ . '/api_crud.php';

    if ($resource === 'dispatches' && file_exists($dispatchFile)) {
        require $dispatchFile;
        exit;
    }
    if ($resource === 'accept' && file_exists($acceptFile)) {
        require $acceptFile;
        exit;
    }

    $crud = array('projects','artisans','reviews','subscriptions','visits','support','clients','workers','suppliers','stats','price_overrides');
    if (in_array($resource, $crud, true) && file_exists($crudFile)) {
        require $crudFile;
        exit;
    }

    json_response(array('ok' => false, 'error' => "Ressource inconnue: $resource"), 400);
} catch (Throwable $e) {
    json_response(array('ok' => false, 'error' => $e->getMessage(), 'file' => basename($e->getFile()), 'line' => $e->getLine()), 500);
}