<?php

namespace auctionforge\inc\api;

use auctionforge\inc\helpers\LotHelper;
use auctionforge\inc\helpers\SettingsHelper;
use auctionforge\inc\model\Auction;

/**
 * Public REST API endpoint for exposing auction data to external sites.
 * Used by the AuctionForge Hub plugin on main/parent sites to aggregate
 * auctions from multiple subdomain installations.
 *
 * Endpoint: GET /wp-json/auctionforge/v1/public/auctions
 * Parameters:
 *   - type: 'upcoming' (default) or 'past'
 *   - limit: max number of auctions to return (default: 50)
 */
class PublicAuctions
{
    public function init()
    {
        add_action('rest_api_init', [$this, 'registerRoutes']);
    }

    public function registerRoutes()
    {
        register_rest_route('auctionforge/v1', '/public/auctions', [
            'methods'             => 'GET',
            'callback'            => [$this, 'getAuctions'],
            'permission_callback' => [$this, 'verifyToken'],
            'args'                => [
                'type' => [
                    'default'           => 'upcoming',
                    'sanitize_callback' => 'sanitize_text_field',
                ],
                'limit' => [
                    'default'           => 50,
                    'sanitize_callback' => 'absint',
                ],
            ],
        ]);
    }

    /**
     * Verify the request carries a valid auth token.
     * Accepts the token via X-AF-Token header or ?token= query param.
     * Uses the same webhook auth token from AuctionForge settings.
     */
    public function verifyToken($request)
    {
        $storedToken = SettingsHelper::getOption('auth_token', '');
        if (empty($storedToken)) {
            // No token configured — deny all access for safety
            return new \WP_Error('af_no_token', 'Public API is not configured (no auth token set)', ['status' => 403]);
        }

        $provided = $request->get_header('X-AF-Token');
        if (empty($provided)) {
            $provided = $request->get_param('token');
        }

        if (empty($provided) || !hash_equals($storedToken, $provided)) {
            return new \WP_Error('af_unauthorized', 'Invalid or missing auth token', ['status' => 401]);
        }

        return true;
    }

    public function getAuctions($request)
    {
        $type  = strtolower($request->get_param('type'));
        $limit = (int) $request->get_param('limit');

        if ($type === 'past') {
            $auctions = Auction::getArchiveAuction();
            if (method_exists(Auction::class, 'filterByEndedDays')) {
                $auctions = Auction::filterByEndedDays($auctions);
            }
            if (!empty($auctions)) {
                usort($auctions, 'sortAuctionDESC');
            }
        } else {
            $auctions = Auction::getActiveAuction(true, false);
            if (!empty($auctions)) {
                usort($auctions, 'sortAuctionASC');
            }
        }

        $result = [];
        $siteUrl = home_url();

        if (!empty($auctions) && is_array($auctions)) {
            foreach ($auctions as $term) {
                if (!($term instanceof \WP_Term)) continue;

                $termId       = $term->term_id;
                $auctionId    = SettingsHelper::getTermOption($termId, 'auction_id');
                $auctionState = SettingsHelper::getTermOption($termId, 'auction_state');
                $auctionDays  = SettingsHelper::getTermOption($termId, 'auction_days');
                $auctionDays = \auctionforge\inc\controllers\CoverImageOverride::applyToDays($auctionDays, $termId);
                $auctionInfo  = SettingsHelper::getTermOption($termId, 'auction_info');
                $catalogLink  = get_category_link($termId);

                if (!is_array($auctionDays)) continue;

                if ($type === 'past') {
                    $auctionDays = array_reverse($auctionDays);
                }

                $countDays = count($auctionDays);

                foreach ($auctionDays as $index => $day) {
                    if ($type === 'upcoming' && isset($day->ended) && $day->ended == true) continue;

                    $link = $catalogLink;
                    $partNumber = null;
                    if ($countDays > 1) {
                        $partNumber = ($type === 'past') ? $countDays - $index : $index + 1;
                        $uri  = parse_url($catalogLink);
                        $link = $uri['path'] . 'part/' . $partNumber . '/';
                    }

                    $image = !empty($day->image) ? $day->image : LotHelper::getPlaceholderImage();

                    $timeZone = '+00:00';
                    if (!empty($day->unknownExactDate)) {
                        $datetime = date('Y-m-d H:i:s', strtotime($day->date . $timeZone));
                    } else {
                        $datetime = date('Y-m-d H:i:s', strtotime($day->date . 'T' . $day->time . $timeZone));
                    }

                    $title = apply_filters('auctionforge_auction_name_build', $term->name, $term);
                    if ($partNumber) $title .= ', Part ' . $partNumber;

                    $result[] = [
                        'auction_id'   => $auctionId,
                        'title'        => $title,
                        'description'  => wp_strip_all_tags($auctionInfo ?? ''),
                        'date'         => substr($datetime, 0, 10),
                        'time'         => substr($datetime, 11, 5),
                        'datetime'     => $datetime,
                        'image'        => $image,
                        'state'        => $auctionState,
                        'link'         => $link,
                        'source_site'  => $siteUrl,
                        'part'         => $partNumber,
                        'day_index'    => $index,
                    ];
                }
            }
        }

        if ($limit > 0 && count($result) > $limit) {
            $result = array_slice($result, 0, $limit);
        }

        return new \WP_REST_Response([
            'success'  => true,
            'count'    => count($result),
            'auctions' => $result,
        ], 200);
    }
}
