<?php

namespace app\controller\manager;

use app\exception\RepositoryException;
use app\model\Account;
use app\model\AccountDataLog;
use app\model\AccountWithdrawalCommission;
use app\repository\AccountRepository;
use app\service\Math;
use Exception;
use think\facade\Db;
use think\response\Json;
use think\response\View;

/**
 * 佣金
 *
 * Class Commission
 * @package app\controller\manager
 */
class Commission extends Base
{
    /**
     * 操作用户佣金
     * */
    public function operation()
    {
        $accountId = input('account_id/d');
        $type      = input('type/s', 'commission');
        if ($this->request->isPost()) {

            $num    = input("num/f", 1);
            $remark = input("remark/s", "");

            $account = AccountRepository::getInstance()->getModel()->findOne(["id" => $accountId], [], function ($q) {
                return $q->lock(true);
            });
            if (empty($account)) {
                return $this->json(4001, "用户不存在");
            }
            Db::startTrans();
            try {

                $saveData = [$type => ($account[$type] + $num)];

                //写入用户记录
                AccountDataLog::log($accountId,
                    "后台操作",
                    $num,
                    $type,
                    AccountDataLog::ACTION_ADMIN_OPERATION,
                    ($account[$type] + $num),
                    $this->auth['nickname'] ?? "",
                    $this->auth['user_id'] ?? 0,
                    $remark
                );

                //保存用户
                $account->save($saveData);

                Db::commit();
                return $this->json();
            } catch (RepositoryException $e) {
                Db::rollback();
                return $this->json("4000", "佣金操作失败:".$e->getMessage());
            } catch (Exception $e) {
                Db::rollback();
                \think\facade\Log::error('佣金操作失败'.$e->getMessage().' file:'.$e->getFile().' line:'.$e->getLine());
                return $this->json("5003", "佣金操作失败");
            }

        }
        $this->data["accountId"] = $accountId;
        $this->data["type"]      = $type;
        return $this->view();
    }

    /**
     * 处理搜索条件
     *
     * @param  array  $searchParams
     * @return array[]
     */
    protected function handleSearch(array $searchParams): array
    {
        $search       = [];
        $accountWhere = [];
        if (!empty($searchParams)) {
            foreach ($searchParams as $key => $param) {
                if (!empty($param)) {
                    if (in_array($key, ['created_at', 'change_type', 'action'])) {
                        switch ($key) {
                            case 'created_at':
                            case 'action':
                                $search[] = ['self.'.$key, 'like', '%'.$param.'%'];
                                break;
                            case 'change_type':
                                $search[] = $param == 'in' ? ['num', '>', 0] : ['num', '<', 0];
                                break;
                        }
                    } else {
                        $accountWhere[] = [$key, 'like', '%'.$param.'%'];
                    }
                }
            }
        }
        return ['search' => $search, 'accountWhere' => $accountWhere];
    }

    /**
     * 用户佣金排行 按降序排列
     *
     * @return Json|View
     * @throws Exception
     */
    public function index()
    {
        if ($this->request->isPost()) {
            $page    = input('page/d', 1);
            $limit   = input('size/d', 10);
            $params  = input('searchParams');
            $keyword = $params['keyword'] ?? '';

            $where[] = ['phone_active', '=', Account::COMMON_ON];
            $items   = AccountRepository::getInstance()->findList($where, [], $page, $limit, function ($q) use ($keyword) {
                return $q->when(!empty($keyword), function ($qa) use ($keyword) {
                    $qa->where('real_name|mobile|nickname', 'like', '%'.$keyword.'%');
                });
            }, ["commission" => "desc", "id" => "desc"]);

            return $this->json(0, '操作成功', $items);
        }

        return $this->view();
    }

    /**
     * 查看单个用户的佣金记录
     *
     * @throws Exception
     */
    public function personal()
    {
        $accountId = input("account_id/d", 0);
        if ($this->request->isPost()) {
            $page          = input('page/d', 1);
            $limit         = input('size/d', 10);
            $search        = [];
            $search[]      = ["account_id", '=', $accountId];
            $search[]      = ["type", '=', AccountDataLog::TYPE_COMMISSION];
            $items         = AccountDataLog::findList($search, [], $page, $limit,
                function ($q) {
                    return $q->with(["account"]);
                }, ["id" => "desc"]);
            $items['list'] = $items['list']->each(function ($item) {
                $item->nickname  = $item->account->nickname ?? '';
                $item->real_name = $item->account->real_name ?? '';
                $item->mobile    = $item->account->mobile ?? '';
            });
            return $this->json(0, '操作成功', $items);
        }

        $this->data["accountId"] = $accountId;
        return $this->view();
    }

    /**
     * 查看所有用户的佣金记录
     **/
    public function log()
    {
        $accountId = input('account_id', 0);
        if ($this->request->isPost()) {
            $page  = input('page/d', 1);
            $limit = input('size/d', 10);

            $searchParams = input('searchParams', []);

            $accountWhere = [];
            $search       = [];
            $search[]     = ["type", '=', AccountDataLog::TYPE_COMMISSION];
            if ($accountId > 0) {
                $search[] = ["self.account_id", '=', $accountId];
            }

            $searchArr    = $this->handleSearch($searchParams);
            $search       = !empty($searchArr['search']) ? array_merge($search, $searchArr['search']) : $search;
            $accountWhere = !empty($searchArr['accountWhere']) ? array_merge($accountWhere, $searchArr['accountWhere']) : $accountWhere;

            $field = ['self.*', 'a.nickname', 'a.real_name', 'a.mobile'];
            $items = AccountDataLog::findList($search, $field, $page, $limit,
                function ($q) use ($accountWhere) {
                    return $q->alias('self')
                        ->join('account a', 'a.id = self.account_id')
                        ->where($accountWhere);
                }, ["id" => "desc"]);
            return $this->json(0, '操作成功', $items);
        }

        $this->data['accountId']    = $accountId;
        $this->data["changeAction"] = AccountDataLog::commissionAction();

        return $this->view();
    }

    /**
     * 提现列表
     * */
    public function withdrawalList()
    {
        if ($this->request->isPost()) {
            $page  = input('page/d', 1);
            $limit = input('size/d', 10);
            $items = AccountWithdrawalCommission::findList([], [], $page, $limit,
                function ($q) {
                    return $q->with(["account"]);
                }, ["id" => "desc"]);
            return $this->json(0, '操作成功', $items);
        }

        return $this->view();
    }

    /**
     * 审核提现
     * */
    public function check(): Json
    {
        $id     = input("id/d");
        $status = input("status/d", null);
        if (empty($status)) {
            return $this->json(4001, "错误的状态");
        }

        if (!$accountCoinWithdrawal = AccountWithdrawalCommission::findById($id, [])) {
            return $this->json(4001, "该提现信息不存在");
        }
        if ($accountCoinWithdrawal['status'] != AccountWithdrawalCommission::$status_default) {
            return $this->json(4001, "该提现不需要审核");
        }

        $account = AccountRepository::getInstance()->getModel()->findOne(["id" => $accountCoinWithdrawal['account_id']], [], function ($q) {
            return $q->lock(true);
        });
        if (empty($account)) {
            return $this->json(4001, "提现用户信息不存在");
        }
        Db::startTrans();
        try {
            //如果状态是审核失败  退回佣金  写入记录
            if ($status == AccountWithdrawalCommission::$status_fail) {
                //写入--积分佣金日志
                AccountDataLog::log($accountCoinWithdrawal['account']['id'],
                    '提现佣金审核失败,退回',
                    $accountCoinWithdrawal['number'],
                    AccountDataLog::TYPE_COMMISSION,
                    AccountDataLog::ACTION_WITHDRAWAL_RETURN,
                    Math::add($accountCoinWithdrawal['account']['commission'], $accountCoinWithdrawal['number'])
                );
                //退回到账户
                $account->save([
                    'commission' => Math::add($accountCoinWithdrawal['account']['commission'], $accountCoinWithdrawal['number'])
                ]);
            }

            //保存状态
            $accountCoinWithdrawal->save([
                "status"   => $status,
                "operator" => $this->auth["nickname"],
                "audit_at" => date("Y-m-d H:i:s")
            ]);

            Db::commit();
            return $this->json();
        } catch (RepositoryException $e) {
            Db::rollback();
            return $this->json(4000, $e->getMessage());
        } catch (Exception $e) {
            Db::rollback();
            \think\facade\Log::error('佣金提现审核失败'.$e->getMessage().' file:'.$e->getFile().' line:'.$e->getLine());
            return $this->json(5003, "审核失败");
        }
    }

    /**
     * 提现配置
     * */
    public function withdrawalConfig()
    {
        if ($this->request->isPost()) {
            try {
                $data = input("post.");
                $php  = var_export($data, true);
                file_put_contents(config_path().'extra/commission_withdrawal'.'.php', '<?php'.PHP_EOL.'return '.$php.';');
                return $this->json();
            } catch (Exception $e) {
                return $this->json(4001, $e->getMessage());
            }
        }
        \think\facade\Config::load('extra/commission_withdrawal', 'commission_withdrawal');
        $coinWithdrawal     = config('commission_withdrawal');
        $this->data["item"] = $coinWithdrawal;
        return $this->view("/manager/config/commission_withdrawal");

    }
}