<?php
if (!defined('ABSPATH')) exit;

define('WEBABILITY_SCAN_RESULTS_KEY', 'webability_scan_results');
define('WEBABILITY_SCAN_META_KEY', 'webability_scan_meta');
define('WEBABILITY_SCANS_KEY', 'webability_scans');
define('WEBABILITY_ANALYZER_URL', 'https://analyzer.webability.io/analyze-accessibility');

/**
 * AJAX: Trigger a site scan via the analyzer API.
 * Now stores results per-URL so multiple pages can be scanned.
 */
add_action('wp_ajax_webability_acwg_scan', function () {
    if (!current_user_can('manage_options')) {
        wp_send_json_error(['msg' => 'Forbidden'], 403);
    }
    check_ajax_referer('webability_acwg_scanner_nonce', 'nonce');

    $scan_url = isset($_POST['scan_url']) ? esc_url_raw($_POST['scan_url']) : home_url('/');
    if (empty($scan_url)) {
        wp_send_json_error(['msg' => 'Invalid URL']);
    }

    $api_url = add_query_arg([
        'url'         => $scan_url,
        'hardrefresh' => 'true',
    ], WEBABILITY_ANALYZER_URL);

    $resp = wp_remote_get($api_url, [
        'timeout'    => 60,
        'user-agent' => 'WebAbility-WordPress-Plugin/' . WEBABILITY_WIDGET_VERSION,
    ]);

    if (is_wp_error($resp)) {
        wp_send_json_error(['msg' => 'Scan failed: ' . $resp->get_error_message()]);
    }

    $code = wp_remote_retrieve_response_code($resp);
    $body = wp_remote_retrieve_body($resp);
    $data = json_decode($body, true);

    if ($code !== 200 || json_last_error() !== JSON_ERROR_NONE) {
        wp_send_json_error(['msg' => 'Analyzer returned an invalid response (HTTP ' . $code . ')']);
    }

    if (empty($data['analysis']) || !isset($data['analysis']['fixes'])) {
        wp_send_json_error(['msg' => 'No analysis data returned']);
    }

    $fixes   = $data['analysis']['fixes'];
    $summary = isset($data['analysis']['summary']) ? $data['analysis']['summary'] : [];

    // Map each fix to determine if it can be auto-fixed in WordPress
    $mapped = webability_acwg_map_fixes($fixes, $scan_url);

    // Store in multi-URL structure
    $all_scans = get_option(WEBABILITY_SCANS_KEY, []);
    $url_key   = md5($scan_url);
    $now       = current_time('mysql');

    // Try to get page title from the analysis data
    $page_title = '';
    if (!empty($data['analysis']['title'])) {
        $page_title = sanitize_text_field($data['analysis']['title']);
    }
    if (empty($page_title)) {
        $post_id = url_to_postid($scan_url);
        if ($post_id) {
            $page_title = get_the_title($post_id);
        }
    }
    if (empty($page_title)) {
        $page_title = wp_parse_url($scan_url, PHP_URL_PATH) ?: '/';
    }

    $all_scans[$url_key] = [
        'url'          => $scan_url,
        'page_title'   => $page_title,
        'last_scan'    => $now,
        'total_issues' => count($mapped),
        'issues_fixed' => count(array_filter($mapped, function ($f) { return $f['status'] === 'fixed'; })),
        'auto_fixable' => count(array_filter($mapped, function ($f) { return !empty($f['auto_fixable']); })),
        'results'      => $mapped,
    ];

    update_option(WEBABILITY_SCANS_KEY, $all_scans, false);

    // Also keep legacy single-scan options for backward compat with fixer.php
    update_option(WEBABILITY_SCAN_RESULTS_KEY, $mapped, false);
    $meta = [
        'last_scan'    => $now,
        'url'          => $scan_url,
        'total_issues' => count($mapped),
        'auto_fixable' => count(array_filter($mapped, function ($f) { return !empty($f['auto_fixable']); })),
        'summary'      => $summary,
    ];
    update_option(WEBABILITY_SCAN_META_KEY, $meta, false);

    wp_send_json_success([
        'meta'    => $meta,
        'results' => $mapped,
    ]);
});

/**
 * AJAX: Delete a scanned URL from results.
 */
add_action('wp_ajax_webability_acwg_delete_scan', function () {
    if (!current_user_can('manage_options')) {
        wp_send_json_error(['msg' => 'Forbidden'], 403);
    }
    check_ajax_referer('webability_acwg_scanner_nonce', 'nonce');

    $url_key = isset($_POST['url_key']) ? sanitize_text_field($_POST['url_key']) : '';
    if (empty($url_key)) {
        wp_send_json_error(['msg' => 'Missing URL key']);
    }

    $all_scans = get_option(WEBABILITY_SCANS_KEY, []);
    if (isset($all_scans[$url_key])) {
        unset($all_scans[$url_key]);
        update_option(WEBABILITY_SCANS_KEY, $all_scans, false);
    }

    wp_send_json_success(['msg' => 'Scan removed']);
});

/**
 * AJAX: Set active scan URL (load its results into the detail view).
 */
add_action('wp_ajax_webability_acwg_set_active_scan', function () {
    if (!current_user_can('manage_options')) {
        wp_send_json_error(['msg' => 'Forbidden'], 403);
    }
    check_ajax_referer('webability_acwg_scanner_nonce', 'nonce');

    $url_key = isset($_POST['url_key']) ? sanitize_text_field($_POST['url_key']) : '';
    $all_scans = get_option(WEBABILITY_SCANS_KEY, []);

    if (empty($url_key) || !isset($all_scans[$url_key])) {
        wp_send_json_error(['msg' => 'Scan not found']);
    }

    $scan = $all_scans[$url_key];

    // Set as active scan for the fixer to work with
    update_option(WEBABILITY_SCAN_RESULTS_KEY, $scan['results'], false);
    update_option(WEBABILITY_SCAN_META_KEY, [
        'last_scan'    => $scan['last_scan'],
        'url'          => $scan['url'],
        'total_issues' => $scan['total_issues'],
        'auto_fixable' => $scan['auto_fixable'],
    ], false);

    wp_send_json_success(['msg' => 'Active scan set', 'url' => $scan['url']]);
});

/**
 * Map analyzer fixes to WordPress-actionable items.
 */
function webability_acwg_map_fixes($fixes, $scan_url = '') {
    $mapped = [];
    foreach ($fixes as $fix) {
        $item = [
            'selector'      => isset($fix['selector']) ? $fix['selector'] : '',
            'action'        => isset($fix['action']) ? $fix['action'] : 'review',
            'attributes'    => isset($fix['attributes']) ? $fix['attributes'] : [],
            'issue_type'    => isset($fix['issue_type']) ? $fix['issue_type'] : '',
            'description'   => isset($fix['description']) ? $fix['description'] : '',
            'wcag'          => isset($fix['wcag']) ? $fix['wcag'] : '',
            'impact'        => isset($fix['impact']) ? $fix['impact'] : 'moderate',
            'suggested_fix' => isset($fix['suggested_fix']) ? $fix['suggested_fix'] : '',
            'fix_target'    => 'manual',
            'wp_object_id'  => 0,
            'auto_fixable'  => false,
            'status'        => 'open',
        ];

        // Determine fix target and auto-fixability
        $target = webability_acwg_resolve_fix_target($item, $scan_url);
        $item['fix_target']   = $target['type'];
        $item['wp_object_id'] = $target['id'];
        $item['auto_fixable'] = $target['auto'];

        $mapped[] = $item;
    }
    return $mapped;
}

/**
 * Resolve a fix to a WordPress object (attachment, post, or theme hook).
 */
function webability_acwg_resolve_fix_target($fix, $scan_url = '') {
    $selector = $fix['selector'];
    $type     = $fix['issue_type'];

    // Image alt text: look for wp-image-{ID} in selector
    if (in_array($type, ['missing_alt', 'empty_alt_functional'], true)) {
        if (preg_match('/wp-image-(\d+)/', $selector, $m)) {
            $att_id = intval($m[1]);
            if (wp_attachment_is_image($att_id)) {
                return ['type' => 'attachment', 'id' => $att_id, 'auto' => true];
            }
        }
        // Try to resolve by src URL
        if (preg_match('/src=["\']([^"\']+)["\']/', $selector, $m)) {
            $att_id = attachment_url_to_postid($m[1]);
            if ($att_id) {
                return ['type' => 'attachment', 'id' => $att_id, 'auto' => true];
            }
        }
    }

    // Structural/theme-level fixes
    $theme_types = ['missing_focus_indicator', 'bypass_blocks', 'language_of_page'];
    if (in_array($type, $theme_types, true)) {
        return ['type' => 'theme', 'id' => 0, 'auto' => true];
    }

    // Content fixes: headings, links — resolve post from scanned URL first
    $content_types = ['empty_heading', 'multiple_h1', 'empty_link'];
    if (in_array($type, $content_types, true)) {
        $post_id = 0;
        if ($scan_url) {
            $post_id = url_to_postid($scan_url);
        }
        if (!$post_id) {
            $meta = get_option(WEBABILITY_SCAN_META_KEY, []);
            if (!empty($meta['url'])) {
                $post_id = url_to_postid($meta['url']);
            }
        }
        if ($post_id) {
            return ['type' => 'post_content', 'id' => $post_id, 'auto' => true];
        }
    }

    return ['type' => 'manual', 'id' => 0, 'auto' => false];
}

