<?php

namespace App\Services;

use App\Models\User;
use Illuminate\Support\Facades\DB;

/**
 * 注册走势 / 注册域名统计
 */
class RegisterStatService
{
    /**
     * @param string $type today|all
     * @return array{type:string,times:array,member:array,virtual:array,member_total:int,virtual_total:int,...}
     */
    public static function trend(string $type, ?string $startDate, ?string $endDate): array
    {
        $today = date('Y-m-d');
        $startDate = $startDate ?: $today;
        $endDate = $endDate ?: $today;

        if ($type === 'today') {
            $day = $startDate;
            $bucketExpr = "DATE_FORMAT(created_at, '%H:00')";
            $times = [];
            for ($h = 0; $h < 24; $h++) {
                $times[] = sprintf('%02d:00', $h);
            }
            $rangeStart = $day . ' 00:00:00';
            $rangeEnd = $day . ' 23:59:59';
            $meta = ['type' => 'today', 'date' => $day];
        } else {
            $bucketExpr = "DATE_FORMAT(created_at, '%Y-%m-%d')";
            $times = [];
            $cursor = strtotime($startDate);
            $endTs = strtotime($endDate);
            while ($cursor <= $endTs) {
                $times[] = date('Y-m-d', $cursor);
                $cursor = strtotime('+1 day', $cursor);
            }
            $rangeStart = $startDate . ' 00:00:00';
            $rangeEnd = $endDate . ' 23:59:59';
            $meta = [
                'type' => 'all',
                'start_time' => $startDate,
                'end_time' => $endDate,
            ];
        }

        $rows = User::query()
            ->selectRaw("{$bucketExpr} as time_key, `from` as user_from, COUNT(*) as cnt")
            ->whereBetween('created_at', [$rangeStart, $rangeEnd])
            ->groupByRaw("{$bucketExpr}, `from`")
            ->get();

        $memberMap = array_fill_keys($times, 0);
        $virtualMap = array_fill_keys($times, 0);
        foreach ($rows as $row) {
            $key = (string)$row->time_key;
            if (!array_key_exists($key, $memberMap)) {
                continue;
            }
            if ((string)$row->user_from === '2') {
                $virtualMap[$key] += (int)$row->cnt;
            } else {
                $memberMap[$key] += (int)$row->cnt;
            }
        }

        return array_merge($meta, [
            'times' => $times,
            'member' => array_values($memberMap),
            'virtual' => array_values($virtualMap),
            'member_total' => array_sum($memberMap),
            'virtual_total' => array_sum($virtualMap),
        ]);
    }

    /**
     * 域名统计（SQL 分页）
     *
     * @return array{total:int,data:list<array{register_url:string,register_count:int}>}
     */
    public static function domain(?string $startDate, ?string $endDate, int $page, int $limit): array
    {
        $domainExpr = "IF(register_domain = '' OR register_domain IS NULL, '未知', register_domain)";

        $base = User::query();
        if ($startDate) {
            $base->where('created_at', '>=', $startDate . ' 00:00:00');
        }
        if ($endDate) {
            $base->where('created_at', '<=', $endDate . ' 23:59:59');
        }

        $grouped = (clone $base)
            ->selectRaw("{$domainExpr} as register_url, COUNT(*) as register_count")
            ->groupByRaw($domainExpr);

        $total = (int)DB::query()->fromSub(
            (clone $grouped),
            'domain_groups'
        )->count();

        $offset = max(0, ($page - 1) * $limit);
        $rows = (clone $grouped)
            ->orderByDesc(DB::raw('register_count'))
            ->offset($offset)
            ->limit($limit)
            ->get();

        $data = $rows->map(fn ($row) => [
            'register_url' => (string)$row->register_url,
            'register_count' => (int)$row->register_count,
        ])->values()->all();

        return ['total' => $total, 'data' => $data];
    }
}
