<?php
/**
 * GrooveSimple — Support Tickets API
 * File: kangaroo.growsimple.io/tickets_api/tickets_api.php
 */

// ─── CONFIG ──────────────────────────────────────────────────────────────────
define('GHL_TOKEN',    'pit-106b66cd-c716-45e5-834b-6344d8fd4e9f');
define('GHL_LOCATION', 'ynCWf3Y4AEJ7hfQ4lVWE');
define('GHL_BASE',     'https://services.leadconnectorhq.com');
define('GHL_VERSION',  '2021-07-28');
define('SCHEMA_ID',    '693062e0b2597829bf523571'); // Support Tickets object ID (for GET)
define('SCHEMA_KEY',   'custom_objects.support_tickets'); // For write operations
// ─────────────────────────────────────────────────────────────────────────────

// CORS — allow GHL iframe origins
$allowed = [
    'https://app.gohighlevel.com',
    'https://app.leadconnectorhq.com',
    'https://kangaroo.growsimple.io',
];
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (in_array($origin, $allowed, true)) {
    header("Access-Control-Allow-Origin: $origin");
} else {
    header("Access-Control-Allow-Origin: *");
}
header('Content-Type: application/json');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Access-Control-Max-Age: 86400');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(204); exit; }

// ─── GHL HTTP HELPER ─────────────────────────────────────────────────────────
function ghl_request(string $method, string $path, array $body = [], bool $debug = false): array {
    $url  = GHL_BASE . $path;
    $ch   = curl_init($url);
    $hdrs = [
        'Authorization: Bearer ' . GHL_TOKEN,
        'Version: '              . GHL_VERSION,
        'Content-Type: application/json',
        'Accept: application/json',
    ];
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 20,
        CURLOPT_CUSTOMREQUEST  => strtoupper($method),
        CURLOPT_HTTPHEADER     => $hdrs,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_FOLLOWLOCATION => true,
    ]);
    if (!empty($body)) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
    }
    $raw    = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $err    = curl_error($ch);
    curl_close($ch);

    if ($debug) return ['url'=>$url,'method'=>$method,'headers'=>$hdrs,'status'=>$status,'raw'=>$raw,'curl_error'=>$err];
    if ($err) return ['success' => false, 'message' => 'cURL error: ' . $err];
    $json = json_decode($raw, true);
    if ($status >= 400) {
        $msg = $json['message'] ?? $json['error'] ?? "HTTP $status";
        return ['success' => false, 'message' => $msg, 'status' => $status, 'raw' => $raw];
    }
    return ['success' => true, 'data' => $json, 'status' => $status];
}

// ─── ROUTER ──────────────────────────────────────────────────────────────────
$action     = $_POST['action'] ?? $_GET['action'] ?? '';
$locationId = GHL_LOCATION;

// (JSONP removed - not needed)

// ─── SMART LISTS STORAGE ─────────────────────────────────────────────────────
// Lists are stored as a JSON file on the server so they persist across
// browsers and devices.  The file lives next to this PHP file.
define('LISTS_FILE', __DIR__ . '/smart_lists.json');

// ACTION: load_lists
if ($action === 'load_lists') {
    if (file_exists(LISTS_FILE)) {
        $raw = file_get_contents(LISTS_FILE);
        $data = json_decode($raw, true);
        if (is_array($data)) {
            echo json_encode(['success' => true, 'lists' => $data]);
            exit;
        }
    }
    // File doesn't exist yet — return empty so frontend uses its defaults
    echo json_encode(['success' => true, 'lists' => null]);
    exit;
}

// ACTION: save_lists
if ($action === 'save_lists') {
    $raw = $_POST['lists'] ?? '';
    if (!$raw) {
        echo json_encode(['success' => false, 'message' => 'No lists data']);
        exit;
    }
    $data = json_decode($raw, true);
    if (!is_array($data)) {
        echo json_encode(['success' => false, 'message' => 'Invalid JSON']);
        exit;
    }
    $ok = file_put_contents(LISTS_FILE, json_encode($data, JSON_PRETTY_PRINT)) !== false;
    echo json_encode(['success' => $ok, 'message' => $ok ? 'Saved' : 'Write failed — check server file permissions']);
    exit;
}
// ─────────────────────────────────────────────────────────────────────────────

// debug action — shows EXACTLY what is sent to GHL
// https://kangaroo.growsimple.io/tickets_api/tickets_api.php?action=debug
if ($action === 'debug') {
    echo json_encode(ghl_request('GET', '/locations/' . GHL_LOCATION, [], true), JSON_PRETTY_PRINT);
    exit;
}

// ═══════════════════════════════════════════════════════════════════════════════
// ACTION: get_support_tickets
// ═══════════════════════════════════════════════════════════════════════════════
if ($action === 'get_support_tickets') {
    $schemaKey = $_POST['schemaKey'] ?? $_GET['schemaKey'] ?? null;

    // Schema ID is hardcoded — confirmed from /objects/ endpoint
    if (!$schemaKey) {
        $schemaKey = SCHEMA_ID;
    }

    $all = []; $page = 1; $pageLimit = 100;
    do {
        $res = ghl_request('POST', "/objects/{$schemaKey}/records/search",
            ['locationId' => $locationId, 'page' => $page, 'pageLimit' => $pageLimit]
        );
        if (!$res['success']) {
            $res = ghl_request('GET', "/objects/{$schemaKey}/records?locationId={$locationId}&page={$page}&pageLimit={$pageLimit}");
        }
        if (!$res['success']) {
            echo json_encode(['success' => false, 'message' => $res['message'], 'schemaKey' => $schemaKey]);
            exit;
        }
        $data    = $res['data'];
        $records = $data['records'] ?? $data['data'] ?? $data['customObjects'] ?? [];
        $total   = $data['meta']['total'] ?? $data['pagination']['total'] ?? $data['total'] ?? 0;
        $all     = array_merge($all, $records);
        $page++;
    } while (count($all) < $total && count($records) === $pageLimit);

    // Normalize each record: find contact ID from any possible location
    $normalized = [];
    foreach ($all as $record) {
        $props = $record['properties'] ?? $record['fields'] ?? [];

        // Try every known location for the contact ID
        $contactId = null;
        $candidates = [
            $record['contactId']                    ?? null,
            $record['contact_id']                   ?? null,
            $record['associatedContactId']           ?? null,
            $record['associated_contact_id']         ?? null,
            $record['contact']['id']                 ?? null,
            $props['associated_contact_id']          ?? null,
            $props['contact_id']                     ?? null,
            $props['contactId']                      ?? null,
            $props['ticket_associated_contact_id']   ?? null,
        ];
        foreach ($candidates as $c) {
            if ($c && strlen(trim((string)$c)) > 5) {
                $contactId = trim((string)$c);
                break;
            }
        }

        // Inject into properties so frontend always finds it in one place
        if ($contactId) {
            $props['__contact_id'] = $contactId;
        }
        $record['properties'] = $props;
        $normalized[] = $record;
    }

    echo json_encode(['success' => true, 'records' => $normalized, 'total' => count($normalized), 'schemaKey' => $schemaKey]);
    exit;
}

// ═══════════════════════════════════════════════════════════════════════════════
// ACTION: update_support_ticket
// ═══════════════════════════════════════════════════════════════════════════════
if ($action === 'update_support_ticket') {
    $schemaKey  = $_POST['schemaKey']  ?? null;
    $recordId   = $_POST['recordId']   ?? null;
    $properties = $_POST['properties'] ?? null;

    if (!$recordId || !$properties) {
        echo json_encode(['success' => false, 'message' => 'Missing recordId or properties']);
        exit;
    }
    if (is_string($properties)) $properties = json_decode($properties, true) ?? [];

    // Try schema ID first (most reliable), then fall back to key
    $attempts = [SCHEMA_ID, SCHEMA_KEY];
    $res = null;
    foreach ($attempts as $tryKey) {
        // locationId MUST be in query string for GHL custom object updates
        $res = ghl_request('PUT', "/objects/{$tryKey}/records/{$recordId}?locationId={$locationId}", ['properties' => $properties]);
        if ($res['success']) break;
    }
    if (!$res['success']) {
        echo json_encode(['success' => false, 'message' => $res['message'], 'tried' => $attempts]);
        exit;
    }

    // ── Sync: if ticket set to resolved → update PC stage to Complete on contact ──
    $updatedProps = is_string($properties) ? json_decode($properties, true) : $properties;
    $newStatus = strtolower(ltrim(trim($updatedProps['ticket_status'] ?? ''), '_'));
    if ($newStatus === 'resolved') {  // matches '_resolved' and 'resolved'
        // Find the contact ID from the ticket record
        $ticketRes = ghl_request('GET', "/objects/" . SCHEMA_ID . "/records/{$recordId}?locationId={$locationId}");
        $ticketRec = $ticketRes['data']['record'] ?? $ticketRes['data'] ?? [];
        $ticketProps = $ticketRec['properties'] ?? $ticketRec['fields'] ?? [];
        $contactId = $ticketRec['contactId']
            ?? $ticketProps['ticket_associated_contact_id']
            ?? $ticketProps['associated_contact_id']
            ?? null;
        if ($contactId) {
            // Get field ID map to write by ID (GHL contact PUT requires field IDs, not keys)
            $fRes = ghl_request('GET', "/locations/{$locationId}/customFields");
            $idMap = [];
            foreach ($fRes['data']['customFields'] ?? [] as $fd) {
                $key = preg_replace('/^contact\./', '', $fd['fieldKey'] ?? $fd['key'] ?? '');
                if ($key) $idMap[$key] = $fd['id'];
            }
            ghl_request('PUT', "/contacts/{$contactId}", [
                'customFields' => [['key' => 'project_center__asset_stage', 'value' => 'Complete']]
            ]);
        }
    }

    echo json_encode(['success' => true, 'record' => $res['data']['record'] ?? $res['data']]);
    exit;
}

// ═══════════════════════════════════════════════════════════════════════════════
// ACTION: create_support_ticket
// ═══════════════════════════════════════════════════════════════════════════════
if ($action === 'create_support_ticket') {
    $schemaKey  = $_POST['schemaKey']  ?? null;
    $properties = $_POST['properties'] ?? null;

    if (!$schemaKey || !$properties) {
        echo json_encode(['success' => false, 'message' => 'Missing schemaKey or properties']);
        exit;
    }
    if (is_string($properties)) $properties = json_decode($properties, true) ?? [];

    // Try schema ID first (more reliable), fall back to passed key
    $res = null;
    foreach ([SCHEMA_ID, SCHEMA_KEY, $schemaKey] as $tryKey) {
        if (!$tryKey) continue;
        $res = ghl_request('POST', "/objects/{$tryKey}/records",
            ['locationId' => $locationId, 'properties' => $properties]
        );
        if ($res['success']) break;
    }
    echo json_encode($res['success']
        ? ['success' => true,  'record'  => $res['data']['record'] ?? $res['data']]
        : ['success' => false, 'message' => $res['message']]
    );
    exit;
}

// ═══════════════════════════════════════════════════════════════════════════════
// ACTION: list_schemas  — open in browser to confirm connection
// https://kangaroo.growsimple.io/tickets_api/tickets_api.php?action=list_schemas
// ═══════════════════════════════════════════════════════════════════════════════
if ($action === 'list_schemas') {
    $res = ghl_request('GET', "/objects/?locationId={$locationId}");
    echo json_encode($res['success'] ? $res['data'] : $res);
    exit;
}

// ═══════════════════════════════════════════════════════════════════════════════
// ACTION: token_test — diagnose exactly what's wrong with the token
// https://kangaroo.growsimple.io/tickets_api/tickets_api.php?action=token_test
// ═══════════════════════════════════════════════════════════════════════════════
if ($action === 'token_test') {
    $results = [];

    // Test 1: Basic location access
    $r1 = ghl_request('GET', "/locations/" . GHL_LOCATION);
    $results['location_access'] = [
        'success' => $r1['success'],
        'message' => $r1['success'] ? 'OK - token valid for this location' : $r1['message'],
    ];

    // Test 2: Objects schema access
    $r2 = ghl_request('GET', "/objects/schemas?locationId=" . GHL_LOCATION);
    $results['objects_scope'] = [
        'success' => $r2['success'],
        'message' => $r2['success'] ? 'OK - Objects:Read scope works' : $r2['message'],
        'object_count' => $r2['success'] ? count($r2['data']['schemas'] ?? $r2['data']['customObjects'] ?? $r2['data']['data'] ?? []) : 0,
    ];

    // Test 3: Show token prefix so we can confirm it's not truncated
    $results['token_info'] = [
        'prefix'  => substr(GHL_TOKEN, 0, 20) . '...',
        'length'  => strlen(GHL_TOKEN),
        'location'=> GHL_LOCATION,
    ];

    echo json_encode($results, JSON_PRETTY_PRINT);
    exit;
}


// ACTION: probe — tries every possible Objects endpoint variation
// https://kangaroo.growsimple.io/tickets_board/tickets_api.php?action=probe
if ($action === 'probe') {
    $results = [];
    $loc = GHL_LOCATION;

    $endpoints = [
        ['ver'=>'2021-07-28', 'path'=>"/objects/schemas?locationId={$loc}"],
        ['ver'=>'2021-07-28', 'path'=>"/objects/?locationId={$loc}"],
        ['ver'=>'2021-07-28', 'path'=>"/custom-objects/schemas?locationId={$loc}"],
        ['ver'=>'2021-04-15', 'path'=>"/objects/schemas?locationId={$loc}"],
        ['ver'=>'2021-04-15', 'path'=>"/objects/?locationId={$loc}"],
    ];

    foreach ($endpoints as $ep) {
        $ch  = curl_init(GHL_BASE . $ep['path']);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT        => 10,
            CURLOPT_CUSTOMREQUEST  => 'GET',
            CURLOPT_HTTPHEADER     => [
                'Authorization: Bearer ' . GHL_TOKEN,
                'Version: ' . $ep['ver'],
                'Content-Type: application/json',
                'Accept: application/json',
            ],
            CURLOPT_SSL_VERIFYPEER => false,
        ]);
        $raw    = curl_exec($ch);
        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        $results[] = [
            'version'  => $ep['ver'],
            'path'     => $ep['path'],
            'status'   => $status,
            'response' => substr($raw, 0, 200),
        ];
    }
    echo json_encode($results, JSON_PRETTY_PRINT);
    exit;
}


// ═══════════════════════════════════════════════════════════════════════════════
// ACTION: delete_support_ticket — permanently deletes a record from GHL
// ═══════════════════════════════════════════════════════════════════════════════
if ($action === 'delete_support_ticket') {
    $recordId = $_POST['recordId'] ?? null;
    if (!$recordId) {
        echo json_encode(['success' => false, 'message' => 'Missing recordId']);
        exit;
    }
    // Try schema ID first, then key
    $res = null;
    foreach ([SCHEMA_ID, SCHEMA_KEY] as $tryKey) {
        $res = ghl_request('DELETE', "/objects/{$tryKey}/records/{$recordId}");
        if ($res['success']) break;
    }
    echo json_encode($res['success']
        ? ['success' => true, 'deleted' => $recordId]
        : ['success' => false, 'message' => $res['message']]
    );
    exit;
}

// ═══════════════════════════════════════════════════════════════════════════════
// ACTION: get_contacts_batch — fetch names for an array of contact IDs
// ═══════════════════════════════════════════════════════════════════════════════
if ($action === 'get_contacts_batch') {
    $ids_raw = $_POST['contactIds'] ?? '';
    $ids = is_string($ids_raw) ? json_decode($ids_raw, true) : $ids_raw;
    if (!is_array($ids) || empty($ids)) {
        echo json_encode(['success' => true, 'contacts' => []]);
        exit;
    }
    // Deduplicate and limit
    $ids = array_values(array_unique(array_filter($ids)));
    $ids = array_slice($ids, 0, 200); // max 200 per batch

    $contacts = [];
    foreach ($ids as $cid) {
        if (!$cid) continue;
        // Try with locationId param first, then without
        $res = ghl_request('GET', "/contacts/{$cid}?locationId={$locationId}");
        if (!$res['success']) {
            $res = ghl_request('GET', "/contacts/{$cid}");
        }
        if ($res['success']) {
            // GHL returns contact nested under 'contact' key
            $contact = $res['data']['contact'] ?? $res['data'] ?? [];
            $first = $contact['firstName'] ?? $contact['first_name'] ?? '';
            $last  = $contact['lastName']  ?? $contact['last_name']  ?? '';
            $name  = trim($first . ' ' . $last);
            if (!$name) $name = $contact['name'] ?? $contact['fullName'] ?? '';
            if (!$name) $name = $contact['email'] ?? '';
            if (!$name) $name = $cid;
            $contacts[$cid] = [
                'name'  => $name,
                'email' => $contact['email'] ?? '',
                'phone' => $contact['phone'] ?? $contact['phoneRaw'] ?? '',
            ];
        } else {
            // Don't cache failures — retry next time
            $contacts[$cid] = ['name' => null, 'email' => '', 'phone' => ''];
        }
    }
    echo json_encode(['success' => true, 'contacts' => $contacts]);
    exit;
}

// ═══════════════════════════════════════════════════════════════════════════════
// ACTION: probe_record — returns raw structure of first ticket for debugging
// ═══════════════════════════════════════════════════════════════════════════════
if ($action === 'probe_record') {
    $recordId = $_POST['recordId'] ?? null;
    if ($recordId) {
        $res = ghl_request('GET', "/objects/" . SCHEMA_ID . "/records/{$recordId}?locationId={$locationId}");
        echo json_encode(['success' => true, 'raw' => $res]);
    } else {
        // Get first record
        $res = ghl_request('POST', "/objects/" . SCHEMA_ID . "/records/search",
            ['locationId' => $locationId, 'page' => 1, 'pageLimit' => 3]
        );
        $records = $res['data']['records'] ?? [];
        echo json_encode(['success' => true, 'raw' => $res, 'first_record' => $records[0] ?? null, 'keys' => $records ? array_keys((array)$records[0]) : []]);
    }
    exit;
}

// ═══════════════════════════════════════════════════════════════════════════════
// ACTION: probe_schema — returns exact allowed option values for ticket fields
// ═══════════════════════════════════════════════════════════════════════════════
if ($action === 'probe_schema') {
    $res = ghl_request('GET', "/objects/" . SCHEMA_ID . "?locationId={$locationId}");
    if (!$res['success']) {
        $res = ghl_request('GET', "/objects/" . SCHEMA_KEY . "?locationId={$locationId}");
    }
    $fields = $res['data']['object']['fields'] ?? $res['data']['fields'] ?? [];
    $optionFields = [];
    foreach ($fields as $f) {
        $type = $f['dataType'] ?? $f['type'] ?? '';
        if (in_array($type, ['SINGLE_OPTIONS','RADIO','SELECT','CHECKBOX','MULTIPLE_OPTIONS'])) {
            $key = $f['fieldKey'] ?? $f['key'] ?? '';
            // Strip object prefix
            $key = preg_replace('/^custom_objects\.[^.]+\./', '', $key);
            $optionFields[$key] = [
                'type'    => $type,
                'options' => array_map(function($o){ 
                    return ['label' => $o['label'] ?? $o['name'] ?? $o, 'value' => $o['value'] ?? $o['key'] ?? $o['label'] ?? $o];
                }, $f['options'] ?? $f['choices'] ?? []),
            ];
        }
    }
    echo json_encode(['success' => true, 'option_fields' => $optionFields, 'schema_id' => SCHEMA_ID]);
    exit;
}

echo json_encode(['success' => false, 'message' => "Unknown action: '{$action}'"]);
