<?php
// includes/jobs/enrich-task.php
if (!defined('ABSPATH')) exit;

require_once AFB_PLUGIN_DIR . 'includes/lib/status-store.php';
require_once AFB_PLUGIN_DIR . 'includes/lib/asana-client.php';
require_once AFB_PLUGIN_DIR . 'includes/functions/triagesummary/triagesummary.php';

/* ------------------------------------------------------------------
 * Helper: PUT custom_fields with retry (handles post-create 404 race)
 * ----------------------------------------------------------------*/
if (!function_exists('afb_put_cf_with_retry')) {
    function afb_put_cf_with_retry(string $task_gid, string $pat, array $cf_map, int $max_attempts = 6) : array {
        $attempt  = 0;
        $last     = ['code' => 0, 'body' => null, 'ms' => 0];

        // Backoff schedule (secs): 1,2,3,5,8,13  (approx Fibonacci)
        $delays = [1, 2, 3, 5, 8, 13];

        while ($attempt < $max_attempts) {
            $attempt++;
            $resp = afb_asana_request(
                'PUT',
                "https://app.asana.com/api/1.0/tasks/{$task_gid}",
                $pat,
                ['json' => ['custom_fields' => $cf_map]],
                0 // retries handled here
            );

            $last = [
                'code' => ($resp['code'] ?? 0),
                'body' => $resp['body'] ?? null,
                'ms'   => ($resp['ms'] ?? 0),
            ];

            // Success
            if (in_array($last['code'], [200, 201], true)) {
                return ['ok' => true, 'attempts' => $attempt, 'http' => $last['code'], 'ms' => $last['ms']];
            }

            // Non-retryable classes: 400 (bad payload), 403 (permissions)
            if (in_array($last['code'], [400, 403], true)) {
                break;
            }

            // 404/429/5xx → retry
            $sleep = $delays[min($attempt-1, count($delays)-1)];
            if (function_exists('afb_log')) {
                $body = is_string($last['body']) ? $last['body'] : json_encode($last['body']);
                afb_log("[enrich] PUT CF retry {$attempt}/{$max_attempts} http={$last['code']} waiting={$sleep}s body=" . substr((string)$body,0,300), 'afb-debug.log');
            }
            sleep($sleep);
        }

        return ['ok' => false, 'attempts' => $attempt, 'http' => $last['code'], 'ms' => $last['ms'], 'body' => $last['body']];
    }
}

if (!function_exists('afb_gateway_task_custom_fields')) {
    function afb_gateway_task_custom_fields(string $task_gid, string $pat): array {
        $resp = afb_asana_request(
            'GET',
            "https://app.asana.com/api/1.0/tasks/{$task_gid}?opt_fields=custom_fields.gid,custom_fields.name,custom_fields.type,custom_fields.resource_subtype",
            $pat
        );

        if ((int)($resp['code'] ?? 0) !== 200) {
            return [];
        }

        $decoded = json_decode((string)($resp['body'] ?? ''), true);
        $rows = $decoded['data']['custom_fields'] ?? [];
        return is_array($rows) ? $rows : [];
    }
}

if (!function_exists('afb_gateway_find_task_field_gid')) {
    function afb_gateway_find_task_field_gid(array $rows, string $kind): string {
        $kind = strtolower(trim($kind));
        $patterns = [];
        $exclude = [];

        if ($kind === 'create') {
            $patterns = [
                '/(^|\\b)create\\s+client\\s+gateway(\\b|$)/i',
                '/(^|\\b)create\\s+gateway(\\b|$)/i',
            ];
        } elseif ($kind === 'link') {
            $patterns = [
                '/(^|\\b)client\\s+gateway\\s+link(\\b|$)/i',
                '/(^|\\b)client\\s+gateway(\\b|$)/i',
            ];
            $exclude = [
                '/(^|\\b)create\\s+client\\s+gateway(\\b|$)/i',
                '/(^|\\b)(client\\s+)?gateway\\s*pin(\\b|$)/i',
            ];
        } elseif ($kind === 'pin') {
            $patterns = [
                '/(^|\\b)(client\\s+)?gateway\\s*pin(\\b|$)/i',
            ];
        }

        if (empty($patterns)) {
            return '';
        }

        foreach ($rows as $row) {
            if (!is_array($row)) {
                continue;
            }

            $gid = preg_replace('/\\D+/', '', (string)($row['gid'] ?? ''));
            if ($gid === '') {
                continue;
            }

            $name = trim((string)($row['name'] ?? ''));
            if ($name === '') {
                continue;
            }

            $skip = false;
            foreach ($exclude as $rx) {
                if (preg_match($rx, $name)) {
                    $skip = true;
                    break;
                }
            }
            if ($skip) {
                continue;
            }

            foreach ($patterns as $rx) {
                if (preg_match($rx, $name)) {
                    return $gid;
                }
            }
        }

        return '';
    }
}

/**
 * Fallback attach: Word .doc from HTML (kept from your existing file)
 */
if (!function_exists('afb_attach_word_doc_from_html_fallback')) {
    function afb_attach_word_doc_from_html_fallback(string $task_gid, string $html, string $friendly_name, string $pat): array {
        if (!trim($html)) return ['ok'=>false,'code'=>0,'msg'=>'empty html'];

        // 1) Normalise
        if (function_exists('afb_normalize_html_for_asana')) {
            $safe_html = afb_normalize_html_for_asana($html);
        } else {
            $safe_html = wp_kses_post($html);
        }

        // 2) Word-friendly wrapper
        $css = 'body{font-family:Arial,Helvetica,sans-serif;font-size:12pt}
                p{margin:.5em 0} ul,ol{margin:.5em 1.25em} li{margin:.25em 0}
                a{color:#1155cc} strong{font-weight:bold}';
        $doc_html = "<!DOCTYPE html>
<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word' xmlns='http://www.w3.org/TR/REC-html40'>
<head><meta charset='utf-8'><title>" . esc_html($friendly_name) . "</title><style>{$css}</style></head>
<body>{$safe_html}</body></html>";

        // 3) Write temp file
        $uploads = wp_upload_dir();
        $tmp_dir = trailingslashit($uploads['basedir']) . 'asana-temp';
        if (!file_exists($tmp_dir)) wp_mkdir_p($tmp_dir);
        $filename = sanitize_file_name($friendly_name) . '.doc';
        $tmp_path = trailingslashit($tmp_dir) . $filename;
        if (@file_put_contents($tmp_path, $doc_html) === false) {
            return ['ok'=>false,'code'=>0,'msg'=>'write file error'];
        }

        // 4) Upload to Asana
        $ch = curl_init("https://app.asana.com/api/1.0/tasks/{$task_gid}/attachments");
        curl_setopt_array($ch, [
            CURLOPT_HTTPHEADER     => ["Authorization: Bearer {$pat}"],
            CURLOPT_POST           => true,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POSTFIELDS     => ['file' => new CURLFile($tmp_path, 'application/msword', $filename)],
        ]);
        $resp = curl_exec($ch);
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $ms   = (int) round((curl_getinfo($ch, CURLINFO_TOTAL_TIME) ?: 0) * 1000);
        curl_close($ch);
        @unlink($tmp_path);

        return ['ok' => in_array($code, [200,201], true), 'code'=>$code, 'ms'=>$ms, 'msg'=>$resp ?: ''];
    }
}

if (!function_exists('afb_trigger_gateway_create_url')) {
    function afb_trigger_gateway_create_url(string $create_url): array {
        $url = esc_url_raw(trim($create_url));
        if ($url === '') {
            return [
                'ok'   => false,
                'http' => 0,
                'ms'   => 0,
                'msg'  => 'Skipped: missing Create Gateway URL.',
            ];
        }

        $target_host = strtolower((string)wp_parse_url($url, PHP_URL_HOST));
        $home_host   = strtolower((string)wp_parse_url(home_url('/'), PHP_URL_HOST));

        if ($target_host !== '' && $home_host !== '' && $target_host !== $home_host) {
            return [
                'ok'   => false,
                'http' => 0,
                'ms'   => 0,
                'msg'  => 'Skipped: Create Gateway URL host mismatch.',
            ];
        }

        $started = microtime(true);
        $retried_timeout = false;
        $resp = wp_remote_get($url, [
            'timeout'     => 20,
            'redirection' => 5,
        ]);

        if (is_wp_error($resp)) {
            $error_message = (string) $resp->get_error_message();
            if (strpos($error_message, 'cURL error 28') !== false) {
                $retried_timeout = true;
                $resp = wp_remote_get($url, [
                    'timeout'     => 35,
                    'redirection' => 5,
                ]);
            }
        }

        $ms = (int) round((microtime(true) - $started) * 1000);

        if (is_wp_error($resp)) {
            return [
                'ok'   => false,
                'http' => 0,
                'ms'   => $ms,
                'msg'  => ($retried_timeout ? 'Auto-create retry failed: ' : 'Auto-create failed: ') . sanitize_text_field($resp->get_error_message()),
            ];
        }

        $code = (int) wp_remote_retrieve_response_code($resp);
        if ($code >= 200 && $code < 400) {
            return [
                'ok'   => true,
                'http' => $code,
                'ms'   => $ms,
                'msg'  => 'HTTP ' . $code . ($retried_timeout ? ' (retry)' : ''),
            ];
        }

        $body = sanitize_text_field(wp_strip_all_tags((string) wp_remote_retrieve_body($resp)));
        if ($body !== '') {
            $body = ' ' . substr($body, 0, 140);
        }

        return [
            'ok'   => false,
            'http' => $code,
            'ms'   => $ms,
            'msg'  => 'HTTP ' . $code . $body,
        ];
    }
}

/* -----------------------------------------------------------
 * Enrichment worker
 *  - Sets “Create Client Gateway” CF (new keys) with retries
 *  - Supports legacy keys (dashboard_cf_gid/dashboard_url)
 *  - Multi-home
 *  - Optional .doc attach from submitted HTML copy
 * ----------------------------------------------------------*/
function afb_run_enrich_task(array $payload) {
    $request_id    = (string)($payload['request_id'] ?? '');
    $task_gid      = (string)($payload['task_gid'] ?? '');
    $pat           = (string)($payload['pat'] ?? '');
    $task_name     = (string)($payload['task_name'] ?? '');
    $project_id    = (string)($payload['project_id'] ?? '');

    if (!$request_id || !$task_gid || !$pat) return;

    // Pull secrets if some values weren’t passed in the payload
    $secret = afb_secret_get($request_id) ?: [];

    // New model (preferred): “Create Client Gateway” link
    $create_cf_gid = (string)($payload['gateway_create_cf_gid'] ?? $secret['gateway_create_cf_gid'] ?? '');
    $create_url    = (string)($payload['gateway_create_url']    ?? $secret['gateway_create_url']    ?? '');

    // Legacy names (back-compat)
    if ($create_cf_gid === '' && !empty($payload['dashboard_cf_gid'])) {
        $create_cf_gid = (string)$payload['dashboard_cf_gid'];
    }
    if ($create_url === '' && !empty($payload['dashboard_url'])) {
        $create_url = (string)$payload['dashboard_url'];
    }

    $gateway_creation_mode = strtolower(sanitize_text_field((string)($payload['gateway_creation_mode'] ?? $secret['gateway_creation_mode'] ?? 'manual')));
    if (!in_array($gateway_creation_mode, ['manual', 'automatic'], true)) {
        $gateway_creation_mode = 'manual';
    }

    // Submitted copy (optional attachment)
    $copy_html = (string)($payload['submitted_copy_html'] ?? $secret['submitted_copy_html'] ?? $secret['copy_html'] ?? '');

    $multi_home = (array)($payload['multi_home'] ?? $secret['multi_home'] ?? []);

    // Update status
    afb_status_merge($request_id, ['phase' => 'enrich']);

    /* 1) Write “Create Client Gateway” link CF (with retry) */
    if ($create_cf_gid && $create_url) {
        $task_cf_rows = afb_gateway_task_custom_fields($task_gid, $pat);
        $task_cf_gids = [];
        foreach ($task_cf_rows as $row) {
            if (!is_array($row)) {
                continue;
            }
            $gid = preg_replace('/\D+/', '', (string)($row['gid'] ?? ''));
            if ($gid !== '') {
                $task_cf_gids[$gid] = true;
            }
        }

        if (!isset($task_cf_gids[$create_cf_gid])) {
            $resolved_create_gid = afb_gateway_find_task_field_gid($task_cf_rows, 'create');
            if ($resolved_create_gid !== '') {
                $create_cf_gid = $resolved_create_gid;
                update_option('afb_client_gateway_create_field_gid', $create_cf_gid);
                if (function_exists('afb_log')) {
                    afb_log('[enrich] gateway_create_cf resolved by task field name to gid=' . $create_cf_gid, 'afb-debug.log');
                }
            }
        }

        if (function_exists('afb_log')) {
            afb_log([
                'where'   => 'enrich:set-gateway-create',
                'task'    => $task_gid,
                'project' => $project_id,
                'cf_gid'  => $create_cf_gid,
                'url'     => $create_url
            ], 'afb-debug.log');
        }

        // Ensure the project CF cache is fresh for any later resolvers
        if ($project_id) delete_transient('afb_cf_' . md5($project_id));

        $res = afb_put_cf_with_retry($task_gid, $pat, [ $create_cf_gid => $create_url ], 6);

        $steps = afb_status_get($request_id)['steps'] ?? [];
        $steps[] = [
            'k'  => 'gateway_create_cf',
            'ok' => (bool)$res['ok'],
            'ms' => (int)($res['ms'] ?? 0),
            'msg'=> 'HTTP ' . (int)($res['http'] ?? 0) . ' (attempts ' . (int)($res['attempts'] ?? 0) . ')'
        ];
        afb_status_merge($request_id, ['steps' => $steps]);

        if (!$res['ok'] && function_exists('afb_log')) {
            $body = isset($res['body']) ? (is_string($res['body']) ? $res['body'] : json_encode($res['body'])) : '';
            afb_log('[enrich] gateway_create_cf FAILED http=' . ($res['http'] ?? 0) . ' body=' . substr($body,0,400), 'afb-debug.log');
        }
    } else {
        if (function_exists('afb_log')) {
            afb_log('[enrich] gateway_create_cf SKIPPED (missing cf gid or url)', 'afb-debug.log');
        }
    }

    if ($gateway_creation_mode === 'automatic') {
        $auto_create = afb_trigger_gateway_create_url($create_url);

        $steps = afb_status_get($request_id)['steps'] ?? [];
        $steps[] = [
            'k'  => 'gateway_auto_create',
            'ok' => (bool)($auto_create['ok'] ?? false),
            'ms' => (int)($auto_create['ms'] ?? 0),
            'msg'=> (string)($auto_create['msg'] ?? ''),
        ];
        afb_status_merge($request_id, ['steps' => $steps]);

        if (function_exists('afb_log')) {
            afb_log(
                '[enrich] gateway_auto_create ' .
                (((bool)($auto_create['ok'] ?? false)) ? 'OK' : 'FAILED') .
                ' task=' . $task_gid .
                ' mode=' . $gateway_creation_mode .
                ' msg=' . (string)($auto_create['msg'] ?? ''),
                'afb-debug.log'
            );
        }
    }

    /* 2) Multi-home (optional) */
    foreach ($multi_home as $pid) {
        if (!$pid) continue;
        $r = afb_asana_request(
            'POST',
            "https://app.asana.com/api/1.0/tasks/{$task_gid}/addProject",
            $pat,
            ['json' => ['project' => $pid]]
        );
        $steps = afb_status_get($request_id)['steps'] ?? [];
        $steps[] = [
            'k'  => "addProject:{$pid}",
            'ok' => in_array(($r['code'] ?? 0), [200,201], true),
            'ms' => ($r['ms'] ?? 0),
            'msg'=> 'HTTP ' . ($r['code'] ?? 0)
        ];
        afb_status_merge($request_id, ['steps' => $steps]);
    }

    /* 3) Attach .doc generated from submitted HTML copy (optional) */
    if (trim($copy_html) !== '') {
        // Try likely helper locations (use your exact helper if it exists)
        $candidates = [
            AFB_PLUGIN_DIR . 'task-comms/functions.php',
            AFB_PLUGIN_DIR . 'includes/task-comms.php',
            AFB_PLUGIN_DIR . 'includes/task-comms/functions.php',
            AFB_PLUGIN_DIR . 'task-comms/partials/handlers/email-copy-ajax.php',
        ];
        foreach ($candidates as $file) {
            if (file_exists($file)) require_once $file;
        }

        $ok=false; $code=0; $ms=0; $msg='';
        if (function_exists('afb_attach_word_doc_from_html_once')) {
            try {
                $res = afb_attach_word_doc_from_html_once($task_gid, $copy_html, 'Submitted Copy - ' . $task_name, $pat);
                $ok  = is_array($res) ? !empty($res['ok']) : true;
                $code= is_array($res) ? (int)($res['code'] ?? 200) : 200;
                $ms  = is_array($res) ? (int)($res['ms'] ?? 0) : 0;
                $msg = is_array($res) ? (string)($res['msg'] ?? '') : '';
            } catch (\Throwable $e) {
                $ok=false; $code=0; $ms=0; $msg='helper threw: '.$e->getMessage();
            }
        } else {
            $res = afb_attach_word_doc_from_html_fallback($task_gid, $copy_html, 'Submitted Copy - ' . $task_name, $pat);
            $ok  = (bool)$res['ok']; $code = (int)($res['code'] ?? 0); $ms = (int)($res['ms'] ?? 0); $msg = (string)($res['msg'] ?? '');
        }

        $steps = afb_status_get($request_id)['steps'] ?? [];
        $steps[] = [
            'k'  => 'attach_doc',
            'ok' => $ok,
            'ms' => $ms,
            'msg'=> $msg ? ('HTTP '.$code.' '.substr(wp_strip_all_tags($msg),0,140)) : ('HTTP '.$code)
        ];
        afb_status_merge($request_id, ['steps'=>$steps]);
    }

    afb_status_merge($request_id, ['phase' => 'done']);
}

add_action('afb_enrich_task_event', 'afb_run_enrich_task', 10, 1);
if (function_exists('as_schedule_single_action')) {
    add_action('afb_enrich_task', 'afb_run_enrich_task', 10, 1);
}

/* -----------------------------------------------------------
 * AJAX: trigger enrich immediately (manual)
 * ----------------------------------------------------------*/
function afb_api_enrich_now() {
    $request_id = sanitize_text_field($_POST['request_id'] ?? '');
    if (!$request_id) wp_send_json_error(['message' => 'Missing request_id']);

    $secret   = afb_secret_get($request_id);
    $task_gid = (string)($secret['task_gid'] ?? '');
    $pat      = (string)($secret['pat'] ?? '');
    if (!$task_gid || !$pat) wp_send_json_error(['message' => 'Unknown request_id']);

    $payload = [
        'request_id'            => $request_id,
        'task_gid'              => $task_gid,
        'pat'                   => $pat,
        'task_name'             => (string)($secret['task_name'] ?? ''),
        'submitted_copy_html'   => (string)($secret['submitted_copy_html'] ?? $secret['copy_html'] ?? ''),
        'multi_home'            => (array) ($secret['multi_home'] ?? []),
        // New keys
        'project_id'            => (string)($secret['project_id'] ?? ''),
        'gateway_create_cf_gid' => (string)($secret['gateway_create_cf_gid'] ?? ''),
        'gateway_create_url'    => (string)($secret['gateway_create_url'] ?? ''),
        'gateway_creation_mode' => (string)($secret['gateway_creation_mode'] ?? 'manual'),
        // Legacy keys (still honored)
        'dashboard_cf_gid'      => (string)($secret['dashboard_cf_gid'] ?? ''),
        'dashboard_url'         => (string)($secret['dashboard_url'] ?? ''),
    ];
    afb_run_enrich_task($payload);
    wp_send_json_success(['ok' => true]);
}
add_action('wp_ajax_afb_enrich_now',        'afb_api_enrich_now');
add_action('wp_ajax_nopriv_afb_enrich_now', 'afb_api_enrich_now');
