<?php

namespace addons\webman\controller;

use addons\webman\model\Player;
use addons\webman\model\PlayerLoginRecord;
use addons\webman\model\PlayerRechargeRecord;
use addons\webman\model\PlayerWithdrawRecord;
use ExAdmin\ui\component\common\Html;
use ExAdmin\ui\component\common\Icon;
use ExAdmin\ui\component\echart\BarChart;
use ExAdmin\ui\component\echart\LineChart;
use ExAdmin\ui\component\grid\card\Card;
use ExAdmin\ui\component\grid\statistic\Statistic;
use ExAdmin\ui\component\layout\Divider;
use ExAdmin\ui\component\layout\layout\Layout;
use ExAdmin\ui\component\layout\Row;
use ExAdmin\ui\response\Msg;
use Illuminate\Support\Carbon;
use support\Db;
use support\Response;

/**
 * 数据中心
 */
class IndexController
{
    /**
     * 数据中心
     * @auth true
     */
    public function index(): Layout
    {
        $rechargeData = $this->rechargeData();
        $withdrawData = $this->withdrawData();
        $playerData = $this->playerData();
        $loginData = $this->loginData();
        $layout = Layout::create();
        $layout->row(function (Row $row) use ($rechargeData, $withdrawData, $playerData, $loginData) {
            $row->gutter([10, 10]);
            $row->column(
                Card::create([
                    Row::create()->column(Icon::create('fas fa-money-bill')->style(['fontSize' => '45px', 'color' => '#409eff', 'marginRight' => '20px']), 4),
                    Row::create()->column(Statistic::create()->title(admin_trans('data_center.recharge_all'))->value(floatval($rechargeData['all']))->style(['fontSize' => '45px', 'text-align' => 'center']), 6),
                    Divider::create()->type('vertical')->style(['height' => '4.9em']),
                    Row::create()->column(Statistic::create()->title(admin_trans('data_center.recharge_activity'))->value(floatval($rechargeData['activity']))->style(['fontSize' => '45px', 'text-align' => 'center']), 6),
                    Divider::create()->type('vertical')->style(['height' => '4.9em']),
                    Row::create()->column(Statistic::create()->title(admin_trans('data_center.recharge_regular'))->value(floatval($rechargeData['regular']))->style(['fontSize' => '45px', 'text-align' => 'center']), 6),
                ])->bodyStyle(['display' => 'flex', 'align-items' => 'center'])->hoverable()->extra(Icon::create('MoreOutlined')
                    ->redirect('ex-admin/addons-webman-controller-RechargeRecordController/index'))
                    ->headStyle(['height' => '0px', 'border-bottom' => '0px', 'min-height' => '0px'])
                , 12);

            $row->column(
                Card::create([
                    Row::create()->column(Icon::create('fas fa-money-bill-alt')->style(['fontSize' => '45px', 'color' => '#ff9800', 'marginRight' => '20px']), 6),
                    Row::create()->column(Statistic::create()->title(admin_trans('data_center.withdraw_all'))
                        ->value(floatval($withdrawData['all']))->style(['fontSize' => '45px', 'text-align' => 'center']), 8),
                    Divider::create()->type('vertical')->style(['height' => '4.9em']),
                    Row::create()->column(Statistic::create()->title(admin_trans('data_center.withdraw_self'))
                        ->value(floatval($withdrawData['self']))->style(['fontSize' => '45px', 'text-align' => 'center']), 8),
                ])->bodyStyle(['display' => 'flex', 'align-items' => 'center'])->hoverable()->extra(Icon::create('MoreOutlined')
                    ->redirect('ex-admin/addons-webman-controller-WithdrawRecordController/index'))
                    ->headStyle(['height' => '0px', 'border-bottom' => '0px', 'min-height' => '0px'])
                , 12);

            $row->column(
                Card::create([
                    Row::create()->column(Icon::create('fas fa-user')->style(['fontSize' => '45px', 'color' => '#409eff', 'marginRight' => '20px']), 6),
                    Row::create()->column(Statistic::create()->title(admin_trans('data_center.today_add_player'))
                        ->value($playerData['today'])->style(['fontSize' => '45px', 'text-align' => 'center']), 8),
                    Divider::create()->type('vertical')->style(['height' => '4.9em']),
                    Row::create()->column(Statistic::create()->title(admin_trans('data_center.player_all'))
                        ->value($playerData['all'])->style(['fontSize' => '45px', 'text-align' => 'center']), 8),
                ])->bodyStyle(['display' => 'flex', 'align-items' => 'center'])->hoverable()->extra(Icon::create('MoreOutlined')
                    ->redirect('ex-admin/addons-webman-controller-PlayerController/index'))
                    ->headStyle(['height' => '0px', 'border-bottom' => '0px', 'min-height' => '0px'])
                , 12);
            $row->column(
                Card::create([
                    Row::create()->column(Icon::create('fas fa-user')->style(['fontSize' => '45px', 'color' => '#e91e63', 'marginRight' => '20px']), 6),
                    Row::create()->column(Statistic::create()->title(admin_trans('data_center.today_active_player'))
                        ->value($loginData['today'])->style(['fontSize' => '45px', 'text-align' => 'center']), 8)
                        ->redirect('ex-admin/addons-webman-controller-PlayerController/index',['active_player' => 1]),
                    Divider::create()->type('vertical')->style(['height' => '4.9em']),
                    Row::create()->column(Statistic::create()->title(admin_trans('data_center.mouth_active_player'))
                        ->value($loginData['month'])->style(['fontSize' => '45px', 'text-align' => 'center']), 8)
                        ->redirect('ex-admin/addons-webman-controller-PlayerController/index',['active_player' => 2])
                ])->bodyStyle(['display' => 'flex', 'align-items' => 'center'])->hoverable()
                , 12);
            $row->column(Card::create($this->rechargeChart())->hoverable(), 24);
            $row->column(Card::create($this->withdrawChart())->hoverable(), 12);
            $row->column(Card::create($this->playerChart())->hoverable(), 12);
        });

        return $layout;
    }

    /**
     * 获取活跃玩家数据
     * @return array
     */
    public function loginData(): array
    {
        return [
            'month' => PlayerLoginRecord::whereYear('created_at', date('Y'))->whereMonth('created_at', date('m'))->distinct('player_id')->count(),
            'today' => PlayerLoginRecord::whereDate('created_at', date('Y-m-d'))->distinct('player_id')->count(),
        ];
    }

    /**
     * 获取玩家数据
     * @return array
     */
    public function playerData(): array
    {
        return [
            'all' => Player::count('*'),
            'today' => Player::whereDate('created_at', date('Y-m-d'))->count(),
        ];
    }

    /**
     * 获取充值数据
     * @return array
     */
    public function rechargeData(): array
    {
        return [
            'all' => PlayerRechargeRecord::where('status', PlayerRechargeRecord::STATUS_RECHARGED_SUCCESS)->whereIn('type', [PlayerRechargeRecord::TYPE_REGULAR, PlayerRechargeRecord::TYPE_ACTIVITY, PlayerRechargeRecord::TYPE_ARTIFICIAL])->sum('coins'),
            'activity' => PlayerRechargeRecord::where('status', PlayerRechargeRecord::STATUS_RECHARGED_SUCCESS)->where('type', PlayerRechargeRecord::TYPE_ACTIVITY)->sum('coins'),
            'regular' => PlayerRechargeRecord::where('status', PlayerRechargeRecord::STATUS_RECHARGED_SUCCESS)->where('type', PlayerRechargeRecord::TYPE_REGULAR)->sum('coins'),
            'artificial' => PlayerRechargeRecord::where('status', PlayerRechargeRecord::STATUS_RECHARGED_SUCCESS)->where('type', PlayerRechargeRecord::TYPE_ARTIFICIAL)->sum('coins'),
        ];
    }

    /**
     * 获取提现数据
     * @return array
     */
    public function withdrawData(): array
    {
        return [
            'all' => PlayerWithdrawRecord::where('status', PlayerWithdrawRecord::STATUS_SUCCESS)->sum('coins'),
            'self' => PlayerWithdrawRecord::where('status', PlayerWithdrawRecord::STATUS_SUCCESS)->where('type', PlayerWithdrawRecord::TYPE_SELF)->sum('coins'),
            'artificial' => PlayerWithdrawRecord::where('status', PlayerWithdrawRecord::STATUS_SUCCESS)->where('type', PlayerWithdrawRecord::TYPE_ARTIFICIAL)->sum('coins'),
        ];
    }


    /**
     * 充值趋势图
     * @return LineChart
     */
    public function rechargeChart(): LineChart
    {
        $range = Carbon::now()->subDays(15)->format('Y-m-d');
        $data = PlayerRechargeRecord::whereDate('created_at', '>=', $range)
            ->where('status', PlayerRechargeRecord::STATUS_RECHARGED_SUCCESS)
            ->whereIn('type', [PlayerRechargeRecord::TYPE_REGULAR, PlayerRechargeRecord::TYPE_ACTIVITY, PlayerRechargeRecord::TYPE_ARTIFICIAL])
            ->groupBy('date')
            ->orderBy('date', 'DESC')
            ->get([
                DB::raw('Date(`created_at`) as date'),
                DB::raw('SUM(`coins`) as value')
            ])
            ->toArray();
        $data = $data ? array_column($data, 'value', 'date') : [];
        $xAxis = [];
        $yAxis = [];
        for ($i = 14; $i >= 0; $i--) {
            $date = Carbon::now()->subDays($i)->format('Y-m-d');
            $xAxis[] = $date;
            $yAxis[] = $data[$date] ?? 0;
        }
        return LineChart::create()
            ->height('280px')
            ->hideDateFilter()
            ->header(Html::create(admin_trans('data_center.recharge_chart'))->tag('h2')->style(['text-align' => 'center']))
            ->xAxis($xAxis)
            ->data(admin_trans('data_center.recharge_amount'), $yAxis);
    }

    /**
     * 提现趋势图
     * @return LineChart
     */
    public function withdrawChart(): LineChart
    {
        $range = Carbon::now()->subDays(15)->format('Y-m-d');
        $data = PlayerWithdrawRecord::whereDate('created_at', '>=', $range)
            ->where('status', PlayerWithdrawRecord::STATUS_SUCCESS)
            ->groupBy('date')
            ->orderBy('date', 'DESC')
            ->get([
                DB::raw('Date(`created_at`) as date'),
                DB::raw('SUM(`coins`) as value')
            ])
            ->toArray();
        $data = $data ? array_column($data, 'value', 'date') : [];
        $xAxis = [];
        $yAxis = [];

        for ($i = 14; $i >= 0; $i--) {
            $date = Carbon::now()->subDays($i)->format('Y-m-d');
            $xAxis[] = $date;
            $yAxis[] = $data[$date] ?? 0;
        }

        return LineChart::create()
            ->height('280px')
            ->hideDateFilter()
            ->header(Html::create(admin_trans('data_center.withdraw_chart'))->tag('h2')->style(['text-align' => 'center']))
            ->xAxis($xAxis)
            ->data(admin_trans('data_center.withdraw_amount'), $yAxis);
    }

    /**
     * 上传
     * @return Response|void
     */
    public function myEditorUpload()
    {
        $file = request()->file('file');
        if ($file && $file->isValid()) {
            $size = $file->getSize();
            if ($file->getSize() >= 1024 * 1024) {
                return jsonFailResponse(trans('image_upload_size_fail', ['{size}' => '1M'], 'message'));
            }
            $extension = $file->getUploadExtension();
            if (!in_array($extension, ['png', 'jpg', 'jpeg'])) {
                return jsonFailResponse(trans('image_upload_size_fail', ['{size}' => '1M'], 'message'));
            }
            $uploadName = $file->getUploadName();
            $basePath = public_path() . '/storage/' . date('Ymd') . DIRECTORY_SEPARATOR;
            $baseUrl = env('APP_URL', 'http://127.0.0.1:8787') . '/storage/' . date('Ymd') . '/';
            $uniqueId = hash_file('md5', $file->getPathname());
            $saveFilename = $uniqueId . '.' . $file->getUploadExtension();
            $savePath = $basePath . $saveFilename;
            $file->move($savePath);

            return jsonSuccessResponse('success', [
                'origin_name' => $uploadName,
                'save_name' => $saveFilename,
                'save_path' => $savePath,
                'url' => $baseUrl . $saveFilename,
                'unique_id' => $uniqueId,
                'size' => $size,
                'mime_type' => $file->getUploadMimeType(),
                'extension' => $extension,
            ]);
        }
    }

    /**
     * 新增玩家
     * @return BarChart
     */
    public function playerChart(): BarChart
    {
        $range = Carbon::now()->subDays(15)->format('Y-m-d');
        $data = Player::whereDate('created_at', '>=', $range)
            ->groupBy('date')
            ->orderBy('date', 'DESC')
            ->get([
                DB::raw('Date(`created_at`) as date'),
                DB::raw('COUNT(`id`) as value')
            ])
            ->toArray();
        $data = $data ? array_column($data, 'value', 'date') : [];
        $xAxis = [];
        $yAxis = [];
        for ($i = 14; $i >= 0; $i--) {
            $date = Carbon::now()->subDays($i)->format('Y-m-d');
            $xAxis[] = $date;
            $yAxis[] = $data[$date] ?? 0;
        }
        return BarChart::create()
            ->height('280px')
            ->hideDateFilter()
            ->header(Html::create(admin_trans('data_center.player_chart'))->tag('h2')->style(['text-align' => 'center']))
            ->xAxis($xAxis)
            ->data(admin_trans('data_center.player_amount'), $yAxis);
    }

    /**
     * 活動圖片上傳
     * @return Msg|Response
     */
    public function activityUpload()
    {
        $file = request()->file('file');
        if ($file && $file->isValid()) {
            if ($file->getSize() >= 1024 * 1024 * 5) {
                return message_error(trans('image_upload_size_fail', ['{size}' => '5M'], 'message'));
            }
            $extension = $file->getUploadExtension();
            if (!in_array($extension, ['png', 'jpg', 'jpeg'])) {
                return message_error(trans('image_upload_fail', [], 'message'));
            }
            $basePath = public_path() . '/storage/' . date('Ymd') . DIRECTORY_SEPARATOR;
            $baseUrl = env('APP_URL', 'http://127.0.0.1:8787') . '/storage/' . date('Ymd') . '/';
            $uniqueId = hash_file('md5', $file->getPathname());
            $saveFilename = $uniqueId . '.' . $file->getUploadExtension();
            $savePath = $basePath . $saveFilename;
            $file->move($savePath);

            return jsonSuccessResponse('success', [$baseUrl . $saveFilename]);
        } else {
            return message_error(trans('image_upload_fail', [], 'message'));
        }
    }
}