<?php

namespace app\controller\manager\account;

use app\controller\manager\Base;
use app\exception\RepositoryException;
use app\model\AccountTag;
use app\model\Account as AccountModel;
use app\model\Order;
use app\repository\AccountRepository;
use app\repository\OrderRepository;
use app\service\Math;
use Exception;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\Log;
use think\response\Json;
use think\response\Redirect;
use think\response\View;

/**
 * 用户管理
 *
 * Class Footmarks
 * @package app\controller\manager
 */
class Index extends Base
{
    protected $noNeedLogin = ['getAccountList'];

    /**
     * 详情
     *
     * @return View
     * @throws RepositoryException
     */
    public function detail(): View
    {
        $id   = input('id/d', 0);
        $item = AccountRepository::getInstance()->findById($id);

        $statusList    = [
            Order::STATUS_SHIPPED, Order::STATUS_ORDER_PLACED, Order::STATUS_COMPLETED
        ];
        $consumption   = OrderRepository::getInstance()->userOrderList($id, [], 1, 0, $statusList);
        $orderNum      = 0;
        $orderScoreNum = 0;
        $totalPrice    = 0;
        $totalScore    = 0;
        $consumption->each(function ($item) use (&$totalPrice, &$totalScore, &$totalCoin, &$orderScoreNum, &$orderNum) {
            if ($item->is_score == AccountModel::COMMON_ON) {
                $orderScoreNum += 1;
            } else {
                $orderNum += 1;
            }
            $totalPrice += $item->price;
            $totalScore += $item->score;
        });
        $item['total_price']     = Math::fen2Yuan($totalPrice);
        $item['order_num']       = $orderNum;
        $item['order_score_num'] = $orderScoreNum;
        $item['order_newest']    = $consumption->toArray()[0] ?? [];

        $this->data['item'] = $item;

        return $this->view();
    }

    /**
     * 编辑
     *
     * @return Redirect|Json|View
     * @throws Exception
     */
    public function edit()
    {
        $id = input('id/d', 0);
        if (!$info = AccountRepository::getInstance()->findById($id)) {
            if ($this->request->isPost()) {
                return $this->json(4000, '用户不存在');
            } else {
                return $this->error('用户不存在');
            }
        }

        if ($this->request->isPost()) {
            $item     = input('post.');
            $validate = $this->validateByApi($item, [
                'nickname' => 'require',
            ]);

            if ($validate !== true) {
                return $validate;
            }

            try {
                $info->save($item);
                return $this->json();
            } catch (ValidateException $e) {
                return $this->json(4001, $e->getError());
            }
        }

        $this->data['item'] = $info;

        return $this->view();
    }

    /**
     * 单个字段编辑
     *
     * @return Json
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     * @throws Exception
     */
    public function modify(): Json
    {
        if ($this->request->isPost()) {
            $item     = input('post.');
            $validate = $this->validateByApi($item, [
                'field' => 'require',
                'value' => 'require',
            ]);

            if ($validate !== true) {
                return $validate;
            }

            if (!$info = AccountModel::findById($item['id'])) {
                return $this->json(4001, '记录不存在');
            }

            $update = [$item['field'] => $item['value']];

            try {
                $info->save($update);
                return $this->json();
            } catch (ValidateException $e) {
                return $this->json(4001, $e->getError());
            }
        }
        return $this->json(4000, '非法请求');
    }

    /**
     * 列表
     *
     * @return View|Json
     * @throws Exception
     */
    public function index()
    {
        if ($this->request->isPost()) {
            $page         = input('page/d', 1);
            $size         = input('size/d', 20);
            $searchParams = input('searchParams');
            $search       = [];
            $other        = [];
            if ($searchParams) {
                foreach ($searchParams as $key => $param) {
                    if ($key == 'tag' && !empty($param)) {
                        $other['tag_id'] = $param;
                        continue;
                    }
                    if ($param || $param == '0') {
                        $search[] = [$key, 'like', '%'.$param.'%'];
                    }
                }
            }

            $search[] = ['phone_active', '=', AccountModel::COMMON_ON];

            try {
                $items = AccountRepository::getInstance()->getAndHandleAccountList($search, [], $page, $size, function ($q) use ($other) {
                    return $q->when(isset($other['tag_id']), function ($query) use ($other) {
                        $query->leftJoin('account_tag_pivot atp', 'atp.account_id = id')->where('atp.tag_id', $other['tag_id']);
                    });
                });
                return $this->json(0, '操作成功', $items);
            } catch (RepositoryException $e) {
                return $this->json(4001, $e->getMessage());
            } catch (Exception $e) {
                return $this->json(5001, '获取用户列表失败'.$e->getMessage());
            }
        }

        $this->data['tagList'] = AccountTag::getTags();

        return $this->view();
    }

    /**
     * 分配客户标签
     *
     * @return View|Json
     * @throws Exception
     */
    public function tag()
    {
        $id = input('id/s', '');
        if ($this->request->isPost()) {
            $ids   = input('ids/s');
            $tagId = input('tag_id/s');
            if (empty($ids)) {
                return $this->json(4001, '请选择要操作的用户');
            }

            if (empty($tagId)) {
                return $this->json(4001, '请选择分配的标签');
            }

            $ids  = explode(',', $ids);
            $tags = explode(',', $tagId);

            Db::startTrans();
            try {
                AccountRepository::getInstance()->setTagByBatch($ids, $tags);
                Db::commit();
                return $this->json(0, '操作成功');
            } catch (RepositoryException $e) {
                Db::rollback();
                return $this->json(4001, $e->getMessage());
            } catch (Exception $e) {
                Db::rollback();
                Log::error('分配客户标签失败'.$e->getMessage());
                return $this->json(5001, '分配客户标签失败');
            }
        }

        $tagList = AccountTag::order('sort', 'desc')->order('id', 'asc')->select()->toArray();

        $this->data['tagList'] = json_encode($tagList, JSON_UNESCAPED_UNICODE);
        $this->data['id']      = $id;

        return $this->view();
    }

    /**
     * 获取客户列表
     *
     * @return Json
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException|Exception
     */
    public function getAccountList(): Json
    {
        if ($this->request->isPost()) {
            $keyword = input('keyword/s', '');
            $page    = input('page/d', 1);
            $size    = input('size/d', 10);
            $id      = input('id', '');

            $relationIds = explode(',', $id);//已选记录

            $where = [];
            if (!empty($keyword)) {
                $where[] = ['nickname|real_name|mobile', 'like', '%'.$keyword.'%'];
            }

            $res = AccountModel::findList($where, ['id', 'nickname', 'real_name', 'mobile'], $page, $size);

            if ($res['total'] > 0 && $relationIds) {
                $res['list'] = $res['list']->toArray();
                foreach ($res['list'] as &$item) {
                    $item['name_text'] = sprintf("昵称:%s;真实姓名:%s,手机号:%s", $item['nickname'], $item['real_name'], $item['mobile']);
                    if (count($relationIds) > 0 && in_array($item['id'], $relationIds)) {
                        $item['selected'] = true;
                    }
                }
            }

            return $this->json(0, '操作成功', $res);
        }
        return $this->json(4001, '非法请求');
    }
}