<?php

namespace Pixeldev\SquareWooSync\REST;

use Pixeldev\SquareWooSync\Abstracts\RESTController;
use Pixeldev\SquareWooSync\Admin\Helpers\BulkMatchProductsJob;
use Pixeldev\SquareWooSync\Square\SquareInventory;
use Pixeldev\SquareWooSync\Logger\Logger;
use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Response;

if (!defined('ABSPATH')) {
    exit;
}

/**
 * REST controller for the bulk-match background job (free variant — simple
 * products only).
 */
class BulkMatchController extends RESTController
{
    protected $namespace = 'sws/v1';
    protected $base      = 'bulk-match';

    public function register_routes()
    {
        register_rest_route($this->namespace, '/' . $this->base . '/status', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [$this, 'get_status'],
                'permission_callback' => [$this, 'check_permission'],
            ],
        ]);
        register_rest_route($this->namespace, '/' . $this->base . '/report', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [$this, 'get_report'],
                'permission_callback' => [$this, 'check_permission'],
            ],
        ]);
        register_rest_route($this->namespace, '/' . $this->base . '/start', [
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [$this, 'start'],
                'permission_callback' => [$this, 'check_permission'],
            ],
        ]);
        register_rest_route($this->namespace, '/' . $this->base . '/cancel', [
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [$this, 'cancel'],
                'permission_callback' => [$this, 'check_permission'],
            ],
        ]);
        register_rest_route($this->namespace, '/' . $this->base . '/link', [
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [$this, 'link_suggested'],
                'permission_callback' => [$this, 'check_permission'],
            ],
        ]);
    }

    public function get_status(WP_REST_Request $request): WP_REST_Response
    {
        $progress = BulkMatchProductsJob::get_progress();
        unset($progress['product_ids'], $progress['linked_map']);
        return new WP_REST_Response($progress, 200);
    }

    public function get_report(WP_REST_Request $request): WP_REST_Response
    {
        return new WP_REST_Response(BulkMatchProductsJob::get_report(), 200);
    }

    public function start(WP_REST_Request $request): WP_REST_Response
    {
        $result = BulkMatchProductsJob::start();
        unset($result['progress']['product_ids'], $result['progress']['linked_map']);
        return new WP_REST_Response($result, 200);
    }

    public function cancel(WP_REST_Request $request): WP_REST_Response
    {
        $result = BulkMatchProductsJob::cancel();
        unset($result['progress']['product_ids'], $result['progress']['linked_map']);
        return new WP_REST_Response($result, 200);
    }

    /**
     * Manually link a Woo simple product to a Square ITEM id surfaced from the
     * "needs review" suggestions. Variable products are rejected — that's a
     * Pro feature.
     */
    public function link_suggested(WP_REST_Request $request): WP_REST_Response
    {
        $woo_id    = (int) $request->get_param('woo_id');
        $square_id = sanitize_text_field((string) $request->get_param('square_id'));
        $product   = $woo_id ? wc_get_product($woo_id) : null;

        if (!$product || '' === $square_id) {
            return new WP_REST_Response(['success' => false, 'message' => 'Invalid product or Square id.'], 400);
        }
        if ($product->is_type('variable')) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'Variable products are not supported in the free version. Upgrade to Pro to match variations.',
            ], 400);
        }
        if (!empty(get_post_meta($woo_id, 'square_product_id', true))) {
            return new WP_REST_Response(['success' => false, 'message' => 'Already linked.'], 409);
        }

        global $wpdb;
        $exists = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = 'square_product_id' AND meta_value = %s LIMIT 1",
                $square_id
            )
        );
        if ($exists) {
            return new WP_REST_Response(['success' => false, 'message' => 'That Square item is already linked to another product.'], 409);
        }

        $square = new SquareInventory();
        $resp   = $square->square_api_request('/catalog/object/' . rawurlencode($square_id), 'GET');
        if (empty($resp['success']) || empty($resp['data']['object'])) {
            return new WP_REST_Response(['success' => false, 'message' => 'Could not load Square item.'], 502);
        }
        $square_object = $resp['data']['object'];
        if (($square_object['type'] ?? '') !== 'ITEM') {
            return new WP_REST_Response(['success' => false, 'message' => 'Not an ITEM.'], 400);
        }
        $square_variations = $square_object['item_data']['variations'] ?? [];
        if (empty($square_variations)) {
            return new WP_REST_Response(['success' => false, 'message' => 'Square item has no variations.'], 400);
        }

        $simple_sku   = (string) $product->get_sku();
        $variation_id = '';
        if ('' !== $simple_sku) {
            foreach ($square_variations as $sv) {
                if (($sv['item_variation_data']['sku'] ?? '') === $simple_sku) {
                    $variation_id = $sv['id'] ?? '';
                    break;
                }
            }
        }
        if ('' === $variation_id) {
            $variation_id = $square_variations[0]['id'] ?? '';
        }

        update_post_meta($woo_id, 'square_product_id', $square_id);
        if ('' !== $variation_id) {
            update_post_meta($woo_id, 'square_variation_id', $variation_id);
        }

        Logger::log('success', 'Bulk match (manual) linked: ' . $product->get_title(), [
            'product_id'     => $woo_id,
            'square_item_id' => $square_id,
        ]);

        // Update report so the UI can refresh.
        $report = BulkMatchProductsJob::get_report();
        foreach ($report['needs_review'] as $i => $entry) {
            if ((int) $entry['woo_id'] === $woo_id) {
                unset($report['needs_review'][$i]);
            }
        }
        $report['needs_review'] = array_values($report['needs_review']);
        $report['matched'][]    = [
            'woo_id'      => $woo_id,
            'name'        => $product->get_name(),
            'edit_link'   => get_edit_post_link($woo_id, 'raw'),
            'sku'         => $product->get_sku(),
            'square_id'   => $square_id,
            'square_name' => $square_object['item_data']['name'] ?? '',
        ];
        update_option(BulkMatchProductsJob::REPORT_OPTION, $report, false);

        return new WP_REST_Response([
            'success' => true,
        ], 200);
    }
}
