<?php
// A2c云控 — 测试脚本（短链/长链 + Real Browser 拦截 API，对齐生产 A2cSpider）

require_once __DIR__ . '/AbstractScrmSpider.class.php';
require_once __DIR__ . '/SplitPageUrlResolver.php';

class A2c extends AbstractScrmSpider
{
    const API_LIST  = '/api/talk/counter/share/record/list';

    const API_DETAILS = '/api/talk/counter/share/detail';

    const API_COUNT = '';

    const DEFAULT_PER_PAGE_COUNT = 20;

    /** @var string */
    private $pageUrl;

    /** @var string */
    private $account;

    /** @var string */
    private $password;

    /** @var UnifiedScrmData */
    private $unifiedData;

    /** @var string HTTP 预解析后的落地 URL */
    private $landingUrl = '';

    public function __construct($pageUrl, $account, $password, $nodeHost = 'http://127.0.0.1:3001')
    {
        parent::__construct($nodeHost);
        $this->account = $account;
        $this->password = $password;
        $this->pageUrl = $pageUrl;
        $this->landingUrl = SplitPageUrlResolver::resolveFinalUrl($pageUrl);
        $this->unifiedData = new UnifiedScrmData();
    }

    protected function getSpiderConfig()
    {
        $antiBot = $this->buildAntiBotConfig();

        $this->logDebug('a2c spider config', [
            'pageUrl'              => $this->pageUrl,
            'landingUrl'           => $this->landingUrl,
            'sessionKey'           => $antiBot['sessionKey'] ?? '',
            'cfClearanceRequired'  => $antiBot['cfClearanceRequired'] ?? null,
        ]);

        return [
            'pageUrl'        => $this->pageUrl,
            'listApi'        => self::API_LIST,
            'detailApi'      => self::API_DETAILS,
            'listMethod'     => 'POST',
            'paginationMode' => self::MODE_UI,
            'authActions'    => [
                ['type' => 'wait', 'ms' => 2000],
            ],
            'antiBot'        => $antiBot,
        ];
    }

    /**
     * A2C：业务域 + 分享 id 会话；短链仍作 pageUrl，landingUrlHint 供 Node 直达长链
     *
     * @return array<string, mixed>
     */
    private function buildAntiBotConfig()
    {
        $sessionScope = $this->resolveA2cSessionScope();

        return [
            'enabled'                => true,
            'profile'                => 'real',
            'turnstile'              => true,
            'solverFallback'         => true,
            'cfClearanceRequired'    => false,
            'sessionKey'             => 'a2c:' . $sessionScope,
            'challengeTimeoutMs'     => 60000,
            'landingUrlHint'         => $this->landingUrl,
            'cfCloudflareSolver'     => true,
            'cfChallengeMode'        => 'managed',
            'businessHostHint'       => $this->resolveA2cSessionHost(),
            'postCfReadyUrlContains' => '/visitors/counter/share',
            'postCfReadySelector'    => '.el-table',
            'postCfReadyApiUrl'      => '/api/talk/counter/share/record/list',
            'postCfReadyTimeoutMs'   => 60000,
            'postCfSettleMs'         => 500,
            'postCfSpaWaitMs'        => 8000,
        ];
    }

    /**
     * A2C 业务域 host
     */
    private function resolveA2cSessionHost()
    {
        $candidates = [];
        if ($this->landingUrl !== '') {
            $candidates[] = (string) parse_url($this->landingUrl, PHP_URL_HOST);
        }
        $candidates[] = (string) parse_url($this->pageUrl, PHP_URL_HOST);

        foreach ($candidates as $host) {
            $host = strtolower(trim($host));
            if ($host !== '' && strpos($host, 'a2c.chat') !== false) {
                return $host;
            }
        }

        return 'user.a2c.chat';
    }

    /**
     * A2C 会话 scope：host + share id
     */
    private function resolveA2cSessionScope()
    {
        $host = $this->resolveA2cSessionHost();
        $shareId = $this->extractA2cShareId($this->pageUrl);
        if ($shareId === '' && $this->landingUrl !== '') {
            $shareId = $this->extractA2cShareId($this->landingUrl);
        }

        return $shareId !== '' ? $host . ':' . $shareId : $host;
    }

    private function extractA2cShareId($url)
    {
        $query = (string) parse_url($url, PHP_URL_QUERY);
        if ($query === '') {
            return '';
        }
        parse_str($query, $params);

        return isset($params['id']) ? trim((string) $params['id']) : '';
    }

    protected function extractListTotalPages($listFirstPageData, $countData = null)
    {
        $default_per_page_count = self::DEFAULT_PER_PAGE_COUNT;
        $this->unifiedData->total = $listFirstPageData['data']['total'];

        if ($listFirstPageData['data']['total'] <= $default_per_page_count) {
            return 1;
        }

        return (int) ceil($listFirstPageData['data']['total'] / $default_per_page_count);
    }

    protected function buildListPageParams($page)
    {
        return ['page' => $page, 'pageSize' => self::DEFAULT_PER_PAGE_COUNT];
    }

    protected function getUiPaginationConfig()
    {
        return [
            'nextBtnSelector' => '.btn-next',
            'waitMs'          => 2000,
        ];
    }

    protected function parseToUnifiedData($detailData, $allListPagesData)
    {
        $unifiedData = $this->unifiedData;

        if ($detailData) {
            $unifiedData->todayNewCount = (int) ($detailData['data']['newFollowersToday'] ?? 0);
        }

        foreach ($allListPagesData as $pageRaw) {
            $records = $pageRaw['data']['rows'] ?? [];
            foreach ($records as $item) {
                if (!empty($item['account'])) {
                    $number = $item['account'];
                    $isOnline = (isset($item['numberStatus']) && (int) $item['numberStatus'] === 1);
                    $unifiedData->addNumber($number, $isOnline, (int) ($item['newFollowersToday'] ?? 0));
                }
            }
        }

        return $unifiedData;
    }
}
