<?php

namespace Modules\Project\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Encore\Admin\Auth\Database\Administrator;
use Encore\Admin\Auth\Database\OperationLog;
use Illuminate\Support\Facades\DB;
use Modules\Base\Entities\User;
use Modules\Project\Entities\WalletLogDaily;
use Modules\Project\Services\WalletLogTypes;
use SMG\Admin\Controllers\HasResourceActions;
use SMG\Admin\DefaultCsvExporter;
use SMG\Admin\Form;
use SMG\Admin\Grid;
use SMG\Admin\Layout\Content;
use SMG\Wallet\Wallet;
use SMG\Wallet\WalletLog;
use Symfony\Component\HttpFoundation\Response;

class WalletController extends Controller
{
    use HasResourceActions;

    /**
     * Index interface.
     *
     * @param Content $content
     *
     * @return mixed
     */
    public function index(Content $content)
    {
        return $content
            ->header('资产列表')
            ->body($this->grid());
    }

    /**
     * Make a grid builder.
     *
     * @return Grid
     */
    protected function grid()
    {
        $total = $this->getWalletTotal();

        $grid = new Grid(new User);

        $grid->model()->with('wallet');

        $grid->id('Id')->totalRow('总计:');
        $grid->name('姓名');
        $grid->phone('手机')->display(function ($v) {
            return '<a href="'.manage_url('user?id='.$this->id).'">'.$v.'</a>';
        });
        $types = array_except(config('wallet.wallet_type', []), config('wallet.admin.hide_types', []));
        foreach ($types as $type => $name) {
            $type_total = $total[$type.'_total'] ?? '0';
            $grid->column('wallet.'.$type, $name)->totalRow($type_total);
            //$grid->column('wallet.'.$type, $name);
        }

        $grid->column('wallet.updated_at', '变动时间');

        $grid->disableCreateButton();
        $grid->disableRowSelector();

        $grid->enableFilter();
        $grid->filter(function ($filter) {
            $filter->equal('name', '姓名');
            $filter->equal('phone', '手机号');
        });

        $grid->actions(function ($actions) {
            $actions->disableDelete();
            $actions->disableEdit();
            $actions->disableView();

            $id = $actions->getKey();
            $actions->append('<a href="'.manage_url('wallet/money_log?user_id='.$id).'">明细<i class="fa fa-plus"></i></a>');
            $actions->append('&nbsp;&nbsp;<a href="'.manage_url('wallet/add_point?user_id='.$id).'">增加<i class="fa fa-exchange"></i></a>');
            $actions->append('&nbsp;&nbsp;<a href="'.manage_url('wallet/password?user_id='.$id).'">设置支付密码<i class="fa fa-cog"></i></a>');
        });

        $grid->enableExport();
        $types = array_flip($types);
        array_walk($types, function (&$item) {
            $item = 'wallet.'.$item;
        });
        $columns = ['ID' => 'id', '手机' => 'phone'];
        $columns = array_merge($columns, $types, ['变动时间' => 'wallet.updated_at']);
        $grid->exporter(new DefaultCsvExporter(null, $columns));

        return $grid;
    }

    public function getWalletTotal()
    {
        $types = array_except(config('wallet.wallet_type', []), config('wallet.admin.hide_types', []));
        $wallet_types = array_keys($types);
        $fields = array_map( function ($type){
            return DB::raw("SUM({$type}) AS {$type}_total");
        }, $wallet_types);


        return Wallet::select($fields)->first()->toArray();
    }

    /**
     * @param $id
     *
     * @return string
     */
    protected function userInfoHtml($id)
    {
        $user = is_numeric($id) ? User::findOrFail($id) : $id;

        $html = 'ID: '.$user->id;
        $html .= '<br />手机号：'.$user->phone;

        return $html;
    }

    /**
     * 入金日志
     *
     * @param Content $content
     *
     * @return \Encore\Admin\Layout\Content
     */
    public function moneyLog(Content $content)
    {
        //$user_id = request('user_id', 0);
        //abort_unless($user_id, '\Exception', '参数丢失');

        $grid = new Grid(new WalletLog(), function ($grid) {
            $wallet_types = config('wallet.wallet_type', []);
            $types = config('wallet.types', []);
            //WalletLog::addWalletLogObject('log', OperationLog::class, '');
            $grid->model()->with(['user'])->whereNotIn('wallet_type', config('wallet.admin.hide_types', []))->orderBy('id', 'DESC');

            //$admins = Administrator::pluck('username', 'id');

            $grid->id('Id');
            //$grid->column('user.name', '姓名');
            $grid->column('user.phone', '手机')->display(function ($v) {
                return '<a href="?user_id='.$this->user_id.'">'.$v.'</a>';
            });
            $grid->column('wallet_type', '资产类型')->using($wallet_types);
            $grid->column('type', '变动类型')->using($types);
            $grid->column('value', '变动值');
            $grid->column('note', '备注');
            $grid->column('query_id', '变动类型对应ID')->display(function ($v) {
                if (in_array($this->type, ['parent_reward_1','parent_reward_2','order_reward'])) {
                    return '<a href="/admin/activity_orders?&id='.$v.'">订单'.$v.'</a>';
                }

                return $v;
            });
            $grid->created_at('时间');

            $grid->disableCreateButton();
            $grid->enableExport();
            $columns = ['ID' => 'id', '手机' => 'user.phone', '变动值' => 'value', '资产类型' => function ($row) use ($wallet_types) {
                return $wallet_types[$row->wallet_type];
            }, '变动类型' => function ($row) {
                $v = $row->type;

                return WalletLogTypes::$types[$v] ?? $v;
            }];
            $grid->exporter(new DefaultCsvExporter(null, $columns));

            $grid->enableFilter();
            $grid->filter(function ($filter) use ($wallet_types) {
                $filter->disableIdFilter();
                $filter->equal('user_id', '用户ID');
                $filter->equal('wallet_type', '资产类型')->select($wallet_types);
                $types = config('wallet.types', []);
                if (!empty($types)) {
                    $filter->equal('type', '资产类型')->select($types);
                }
                //$filter->equal('type_id', '操作ID');
                $filter->equal('user.phone', '手机号');
                $filter->equal('query_id', '操作ID');
                $filter->between('created_at', '时间')->datetime();
            });

            $grid->disableRowSelector();
            $grid->disableActions();
        });

        return $content
            ->header('用户资产变动明细')
            ->body($grid);
    }

    public function adminMoneyLog(Content $content)
    {
        //$user_id = request('user_id', 0);
        //abort_unless($user_id, '\Exception', '参数丢失');

        WalletLog::addWalletLogObject('log', OperationLog::class, '');
        $grid = new Grid(new WalletLog(), function ($grid) {
            $wallet_types = config('wallet.wallet_type', []);
            $grid->model()->where('type', 'admin')->with(['user','log'])->whereNotIn('wallet_type', config('wallet.admin.hide_types', []))->orderBy('id', 'DESC');

            $admins = Administrator::pluck('username', 'id')->toArray();

            $grid->id('Id');
            $grid->column('user.phone', '用户手机');
            $grid->column('wallet_type', '资产类型')->using($wallet_types);
            $grid->column('value', '变动值');
            $grid->column('log.user_id', '操作人')->using($admins);
            $grid->created_at('时间');

            $grid->disableCreateButton();
            $grid->enableExport();
            $columns = ['ID' => 'id', '手机' => 'user.phone', '变动值' => 'value', '资产类型' => function ($row) use ($wallet_types) {
                return $wallet_types[$row->wallet_type];
            },  '操作人' => function ($row) use ($admins) {
                return $admins[$row->log->user_id];
            }, '操作时间' => 'created_at'];
            $grid->exporter(new DefaultCsvExporter(null, $columns));

            $grid->enableFilter();
            $grid->filter(function ($filter) use ($wallet_types) {
                $filter->disableIdFilter();
                $filter->equal('wallet_type', '资产类型')->select($wallet_types);
                $filter->equal('user.phone', '手机号');
                $filter->between('created_at', '时间')->datetime();
            });

            $grid->disableRowSelector();
            $grid->disableActions();
        });

        return $content
            ->header('管理员操作资产记录')
            ->body($grid);
    }

    public function daily(Content $content)
    {
        //$user_id = request('user_id', 0);
        //abort_unless($user_id, '\Exception', '参数丢失');

        //WalletLog::addWalletLogObject('log', OperationLog::class, '');
        //$model =
        $grid = new Grid(new WalletLogDaily(), function ($grid) {
            $grid->column('d', '日期');
            $grid->column('money_add', '现金资产增加');
            $grid->column('money_use', '现金资产消耗');
            $grid->column('quota_add', '配额增加');
            $grid->column('quota_use', '配额消耗');
            $grid->column('income_integral_add', '收益资产增加');
            $grid->column('income_integral_use', '收益资产消耗');
            $grid->column('shopping_integral_add', '购物资产增加');
            $grid->column('shopping_integral_use', '购物资产消耗');

            $grid->disableCreateButton();
            $grid->enableExport();
            $columns = ['日期' => 'd', '现金资产增加' => 'money_add', '现金资产消耗' => 'money_use',
                '配额增加' => 'quota_add', '配额消耗' => 'quota_use', '收益资产增加' => 'income_integral_add',
                '收益资产消耗' => 'income_integral_use', '购物资产增加' => 'shopping_integral_add', '购物资产消耗' => 'shopping_integral_use', ];
            $grid->exporter(new DefaultCsvExporter(null, $columns));

            $grid->enableFilter();
            $grid->filter(function ($filter) {
                $filter->disableIdFilter();
                $filter->between('created_at', '时间')->datetime();
            });

            $grid->disableRowSelector();
            $grid->disableActions();
        });

        $all = (new WalletLogDaily())->getTotal();
        $split = '&nbsp;&nbsp;';
        $footer = '总现金资产增加：'.$all->money_add_all;
        $footer .= $split.'总现金资产消耗：'.$all->money_use_all;
        $footer .= $split.'总配额增加：'.$all->quota_add_all;
        $footer .= $split.'总配额消耗：'.$all->quota_use_all;
        $footer .= $split.'总收益资产增加：'.$all->income_integral_add_all;
        $footer .= $split.'总收益资产消耗：'.$all->income_integral_use_all;
        $footer .= $split.'购物资产增加：'.$all->shopping_integral_add_all;
        $footer .= $split.'购物资产消耗：'.$all->shopping_integral_use_all;

        $footer = '<b>'.$footer.'</b>';

        return $content
            ->header('每日资产统计')
            ->body($grid->render().$footer);
    }

    public function addPoint(Content $content)
    {
        $user = User::findOrFail(request('user_id', 0));
        $form = $this->addPointForm($user);

        $response = $form->afterPost(function ($data) use ($user) {
            $operation_id = OperationLog::max('id');
            //$operation_id = time();
            if ($data['value'] > 0) {
                $user->addWallet($data['value'], 'admin', $operation_id, $data['type']);
            } else {
                $user->useWallet(abs($data['value']), 'admin', $operation_id, $data['type']);
            }
            admin_toastr('增加成功');
        });

        if ($response instanceof Response) {
            return $response;
        }

        return $content
            ->header('增加')
            ->body($this->addPointForm($user));
    }

    protected function addPointForm($user)
    {
        $form = new Form(new User);
        $form->setTitle(' ');
        $form->setAction(manage_url('wallet/add_point?user_id='.$user->id));
        $form->html($this->userInfoHtml($user), '用户');
        $types = array_except(config('wallet.wallet_type', []), config('wallet.admin.hide_types', []));
        foreach ($types as $type => $name) {
            $form->html($user->wallet->$type, $name);
        }
        $form->select('type', '增加类型')->options($types)->rules('required|in:'.implode(',', array_keys($types)));
        //$form->number('value', '增加数额')->rules('required|numeric|not_in:0')->help('为负时将扣除');
        $form->decimal('value', '增加数额')->options(['max' => 100000000, 'min' => -99999999,'digits' => 2])->rules('required|numeric|not_in:0')->help('为负时将扣除');

        return $form;
    }

    public function password(Content $content)
    {
        $user = User::findOrFail(request('user_id', 0));
        $form = $this->passwordForm($user);

        $response = $form->afterPost(function ($data) use ($user) {
            $user->setPayPassword($data['password']);
            admin_toastr('重置支付密码成功');
        });

        if ($response instanceof Response) {
            return $response;
        }

        return $content
            ->header('重设支付密码')
            ->body($this->passwordForm($user));
    }

    protected function passwordForm($user)
    {
        $form = new Form(new User);
        $form->setTitle(' ');
        $form->setAction(manage_url('wallet/password?user_id='.$user->id));
        $form->html($this->userInfoHtml($user), '用户');
        $form->password('password', '重置支付密码')->help('6位数字')->rules('required|digits:6');
        $form->password('password2', '重新输入支付密码')->rules('required|same:password');

        return $form;
    }
}
