<?php

declare(strict_types=1);

namespace app\common\service;

use app\admin\model\split\Link;
use app\admin\model\split\Number;
use think\Collection;

/**
 * 分流链接落地页：查链、轮转选号、拼接跳转 URL、访问计数
 */
class SplitRedirectService
{
    private SplitRoundRobinStore $roundRobinStore;

    public function __construct(?SplitRoundRobinStore $roundRobinStore = null)
    {
        $this->roundRobinStore = $roundRobinStore ?? new SplitRoundRobinStore();
    }

    /**
     * 根据链接码解析本次应跳转的加好友 URL；无效时返回 null
     *
     * @param string $linkCode  9 位链接码
     * @param string $clientIp  访客 IP（IP 防护开启时用于国家校验）
     */
    public function resolveRedirectUrl(string $linkCode, string $clientIp = ''): ?string
    {
        $linkCode = SplitLinkCodeService::normalize($linkCode);
        if (!SplitLinkCodeService::isValidFormat($linkCode)) {
            return null;
        }

        $link = Link::where('link_code', $linkCode)
            ->where('status', 'normal')
            ->find();
        if (!$link) {
            return null;
        }

        $ipProtect = (int) $link->getAttr('ip_protect');
        $countries = (string) $link->getAttr('countries');
        if (!SplitIpProtectService::isAllowed($ipProtect, $countries, $clientIp)) {
            return null;
        }

        /** @var Collection<int, Number>|array<int, Number> $numbers */
        $numbers = Number::where('split_link_id', (int) $link['id'])
            ->where('status', 'normal')
            ->order('id', 'asc')
            ->field('id,number,number_type,number_type_custom')
            ->select();

        $count = is_countable($numbers) ? count($numbers) : 0;
        if ($count === 0) {
            return null;
        }

        $linkId = (int) $link->getAttr('id');
        $index = $this->roundRobinStore->nextIndex($linkId, $count);
        $list = $numbers instanceof \think\Collection ? $numbers->all() : (array) $numbers;
        $picked = $list[$index] ?? $list[0] ?? null;
        if ($picked === null) {
            return null;
        }

        $numberType = is_array($picked) ? (string) ($picked['number_type'] ?? '') : (string) $picked->getAttr('number_type');
        $numberValue = is_array($picked) ? (string) ($picked['number'] ?? '') : (string) $picked->getAttr('number');
        $numberCustom = is_array($picked)
            ? (string) ($picked['number_type_custom'] ?? '')
            : (string) $picked->getAttr('number_type_custom');

        $replyText = '';
        if (in_array($numberType, ['whatsapp', 'telegram'], true)) {
            $replyText = SplitAutoReplyService::pickRandomLine((string) $link->getAttr('auto_reply'));
        }

        $redirectUrl = SplitFriendUrlBuilder::build(
            $numberType,
            $numberValue,
            $numberCustom,
            $replyText
        );
        if ($redirectUrl === '') {
            return null;
        }

        $numberId = is_array($picked) ? (int) ($picked['id'] ?? 0) : (int) $picked->getAttr('id');
        if ($numberId > 0) {
            Number::where('id', $numberId)->setInc('visit_count');
        }

        return $redirectUrl;
    }
}
