<?php

declare(strict_types=1);

namespace app\admin\controller;

use app\common\controller\Backend;
use app\common\model\MallClaimLog;
use app\common\model\MallOrder;
use app\common\model\MallUserAsset;
use support\think\Db;
use Webman\Http\Request;
use support\Response;

class Dashboard extends Backend
{
    public function index(Request $request): Response
    {
        $response = $this->initializeBackend($request);
        if ($response !== null) return $response;

        $now = time();
        $todayStart = strtotime(date('Y-m-d', $now) . ' 00:00:00');
        $yesterdayStart = $todayStart - 86400;

        $newPlayersToday = MallUserAsset::where('create_time', '>=', $todayStart)
            ->where('create_time', '<=', $now)
            ->count();

        $yesterdayPointsClaimed = MallClaimLog::where('create_time', '>=', $yesterdayStart)
            ->where('create_time', '<', $todayStart)
            ->sum('claimed_amount');

        $yesterdayRedeemQuery = MallOrder::where('create_time', '>=', $yesterdayStart)
            ->where('create_time', '<', $todayStart);

        $yesterdayRedeemCount = (clone $yesterdayRedeemQuery)->count();
        $yesterdayRedeemPointsCostSum = (clone $yesterdayRedeemQuery)->sum('points_cost');
        $yesterdayRedeemAmountSum = (clone $yesterdayRedeemQuery)->sum('amount');
        $yesterdayRedeemCompletedCount = (clone $yesterdayRedeemQuery)
            ->where('status', MallOrder::STATUS_COMPLETED)
            ->count();
        $yesterdayRedeemRejectedCount = (clone $yesterdayRedeemQuery)
            ->where('status', MallOrder::STATUS_REJECTED)
            ->count();

        $yesterdayRedeemByItem = Db::name('mall_order')
            ->alias('o')
            ->leftJoin('mall_item i', 'i.id = o.mall_item_id')
            ->where('o.create_time', '>=', $yesterdayStart)
            ->where('o.create_time', '<', $todayStart)
            ->group('o.mall_item_id, i.title')
            ->field([
                'o.mall_item_id',
                'i.title',
                Db::raw('COUNT(*) as order_count'),
                Db::raw('SUM(o.points_cost) as points_cost_sum'),
                Db::raw('SUM(o.amount) as amount_sum'),
                Db::raw('SUM(CASE WHEN o.status = "COMPLETED" THEN 1 ELSE 0 END) as completed_count'),
                Db::raw('SUM(CASE WHEN o.status = "REJECTED" THEN 1 ELSE 0 END) as rejected_count'),
            ])
            ->orderRaw('order_count DESC')
            ->select()
            ->toArray();

        $pendingPhysicalToShip = MallOrder::where('type', MallOrder::TYPE_PHYSICAL)
            ->where('status', MallOrder::STATUS_PENDING)
            ->count();
        $grantFailedRetryableCount = MallOrder::where('type', MallOrder::TYPE_BONUS)
            ->where('grant_status', MallOrder::GRANT_FAILED_RETRYABLE)
            ->count();

        return $this->success('', [
            'remark' => get_route_remark(),
            'playx' => [
                'time_range' => [
                    'today_start' => $todayStart,
                    'yesterday_start' => $yesterdayStart,
                    'now' => $now,
                ],
                'new_players_today' => $newPlayersToday,
                'yesterday_points_claimed' => $yesterdayPointsClaimed,
                'yesterday_redeem' => [
                    'order_count' => $yesterdayRedeemCount,
                    'points_cost_sum' => $yesterdayRedeemPointsCostSum,
                    'amount_sum' => $yesterdayRedeemAmountSum,
                    'completed_count' => $yesterdayRedeemCompletedCount,
                    'rejected_count' => $yesterdayRedeemRejectedCount,
                    'by_item' => $yesterdayRedeemByItem,
                ],
                'pending_physical_to_ship' => $pendingPhysicalToShip,
                'grant_failed_retryable' => $grantFailedRetryableCount,
            ],
        ]);
    }
}
