<?php

namespace app\repository;

use app\exception\RepositoryException;
use app\model\Account;
use app\model\Business;
use app\model\CouponMain;
use app\model\Deduction;
use app\model\Recharge;
use app\service\Repository;
use app\traits\account\ApplyStaffTrait;
use app\traits\CouponBillTrait;
use app\traits\CouponMainTrait;
use think\Collection;
use think\Model;

/**
 * 商家域 相关操作
 *
 * Class BusinessRepository
 * @package app\repository
 * @method self getInstance(Model $model = null) static
 */
class BusinessRepository extends Repository
{
    use CouponBillTrait;
    use CouponMainTrait;
    use ApplyStaffTrait;

    /**
     * 根据条件查询列表
     *
     * @param array $where 查询条件
     * @param int $page 默认第一页 0不限制
     * @param int $limit 限制条数 0不限制
     * @param array $order
     * @return array
     * @throws RepositoryException
     */
    public function businessList(array $where = [], int $page = 1, int $limit = 0, array $order = [])
    {
        $q = $this->model->alias("a")
            ->join("account b", "a.code = b.business_code")
            ->field(["a.code as business_code",
                "b.avatar_url",
                "b.nick_name as account_nick_name",
                "a.business_name",
                "a.total_recharge",
                "a.id as basiness_id",
                "a.balance",
                "a.contact_name",
                "a.contact_phone",
                "a.business_address",
                "a.business_license",
                "a.state",
                "a.type_name",
            ])
            ->group("a.id");
        $data = [
            'total' => 0,
            'current' => $page,
            'size' => $limit,
            'list' => new Collection(),
        ];


        if (count($where)) {
            $q = $q->where($where);
        }
        if (count($order)) {
            $q = $q->order($order);
        }
        $data['total'] = $q->count();
        if ($data['total']) {
            if ($limit) {
                if ($page) {
                    $q = $q->page($page);
                }
                $q = $q->limit($limit);
            }

            $data['list'] = $q->select();
        }

        return $data;
    }

    /**
     * 签到券列表
     *
     * @param string $businessCode 商家code
     * @param int $page 默认第一页 0不限制
     * @param int $limit 限制条数 0不限制
     * @param array $order
     * @return array
     * @throws RepositoryException
     */
    public function businessCouponList($where, int $page = 1, int $limit = 0, array $order = ["create_time" => "desc", "id" => "desc"])
    {
        return CouponMain::findList($where, [], $page, $limit, null, $order);
    }

    /**
     * 扣费记录
     *
     * @param string $businessCode 商家code
     * @param int $page 默认第一页 0不限制
     * @param int $limit 限制条数 0不限制
     * @param array $order
     * @return array
     * @throws RepositoryException
     */
    public function businessDeductionList($where, int $page = 1, int $limit = 0, array $order = ["create_time" => "desc", "id" => "desc"])
    {
        return Deduction::findList($where, [], $page, $limit, function ($q) {
            return $q->with(["couponMain","bill","account"]);
        }, $order);
    }

    /**
     * 充值记录
     *
     * @param string $businessCode 商家code
     * @param int $page 默认第一页 0不限制
     * @param int $limit 限制条数 0不限制
     * @param array $order
     * @return array
     * @throws RepositoryException
     */
    public function businessRechargeList($where, int $page = 1, int $limit = 0, array $order = ["create_time" => "desc", "id" => "desc"])
    {
        return Recharge::findList($where, [], $page, $limit, function ($q) {
            return $q->withJoin(["business" => ["business_name"]]);
        }, $order);
    }

    /* 获取所有的商家*/
    public function getBusinessAll()
    {
        return Business::alias("a")
            ->join("account b", "a.code = b.business_code")
            ->field("a.code , a.business_name , a.contact_name")
            ->order("a.id desc")
            ->group("a.id")
            ->select();
    }

    /**
     * 获取单个商家详情
     * @param $businessCode
     * @param bool $lock
     * @return array|Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getBusinessAccount($businessCode, bool $lock = false)
    {
        $business = Business::where("code", $businessCode)->when($lock, function ($q) {
            $q->lock(true);
        })->find();
        if (empty($business)) {
            return null;
        }
        return $business;
    }


    /**
     * 格式化前端输出商户信息
     * @param array $data
     * @param array $formats
     * @return array
     */
    public function formatFrontBusinessInfo(array $data, array $formats=[]): array
    {
        $fields = ['id', 'code', 'business_name', 'business_subtitle', 'business_license',
            'lat', 'lng', 'business_address', 'contact_name', 'contact_phone',
            'create_time', 'type', 'type_name', 'characteristic', 'intro',
            'business_circle', 'business_circle_id', 'background', 'score',
        ];

        if (in_array(1, $formats)) {
            // 返回审批相关字段
            $fields = array_merge($fields, ['state', 'reason']);
        }
        if (in_array(2, $formats)) {
            // 返回关联的平台商相关字段
            $fields = array_merge($fields, [ 'is_agency', 'agency_code']);
        }

        return arrayKeysFilter($data, $fields);
    }

    /**
     * 查看指定商圈下的商家
     * @param $businessCircleId
     * @return Business[]|array|Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getByCircleId($businessCircleId)
    {
        return Business::where("business_circle_id", $businessCircleId)->select();
    }

    /**
     * 平台商下有多少商家
     * @param $agencyCode
     * @return int
     */
    public function agencyHasBusinessCount($agencyCode)
    {
        return Business::where("agency_code", $agencyCode)->count();
    }

    /**
     * 平台商下商家 所持有的签到券数量
     * @param $agencyCode
     * @return int
     */
    public function agencyHasCouponCount($agencyCode)
    {
        return Business::alias("a")
            ->join("coupon_main b", "a.code =b.business_code")
            ->where("a.agency_code", $agencyCode)
            ->sum("b.count");
    }

    /**
     * 统计某个时间段内  商家发布的签到券个数
     * @param $businessId
     * @param $startTime
     * @param $endTime
     */
    public function getTimeListModeReleaseCount($businessCode,$startTime,$endTime)
    {
        return CouponMain::where("business_code",$businessCode)
            ->whereBetweenTime("create_time",$startTime,$endTime)
            ->order("id")
            ->count();
    }
}