<?php

namespace app\admin\controller\coupon;

use app\admin\service\coupon\CouponDetailService;
use app\admin\service\coupon\CouponService;
use app\admin\validate\coupon\CouponValidate;
use app\admin\validate\device\DeviceValidate;
use app\controller\Curd;
use app\model\Coupon;
use app\model\CouponDetail;
use app\model\CouponGoods;
use app\model\Device;
use app\model\Member;
use app\model\SysDept;
use app\model\SysSerial;
use support\Db;
use support\exception\BusinessException;
use support\Log;
use support\Request;
use support\Response;
use Tinywan\Jwt\JwtToken;

class CouponController extends Curd
{
    public function __construct()
    {
        $this->model = new Coupon();
        $this->validate = true;
        $this->validateClass = new CouponValidate();
    }

    /**
     * @Desc 列表
     * @Author Gorden
     * @Date 2024/3/28 15:01
     *
     * @param Request $request
     * @return Response
     * @throws \support\exception\BusinessException
     */
    public function select(Request $request): Response
    {
        $joinCouponCategoryId = $request->get('join_coupon_category_id', []);
        [$where, $format, $limit, $field, $order] = $this->selectInput($request);
        if (!empty($joinCouponCategoryId)) {
            $where['join_coupon_category_id'] = ['in', implode(',', $joinCouponCategoryId)];
        }
        if (!empty($where['coupon_addtimes'])) {
            $where['coupon_addtimes'][0] = strtotime($where['coupon_addtimes'][0]);
            $where['coupon_addtimes'][1] = strtotime($where['coupon_addtimes'][1]);
        }
        if (!empty($where['coupon_id'])) {
            $where['coupon_id'] = ['like', trim($where['coupon_id'])];
        }
        $order = $request->get('order', 'desc');
        $field = $field ?? 'coupon_addtimes';
        $query = $this->doSelect($where, $field, $order);
        return $this->doFormat($query, $format, $limit);
    }

    protected function doSelect(array $where, string $field = null, string $order = 'desc')
    {
        $model = $this->model->with([
            'category' => function ($query) {
                $query->select('category_id', 'category_name');
            },
            'user',
            'detail'
        ]);
        foreach ($where as $column => $value) {
            if (is_array($value)) {
                if ($value[0] === 'like' || $value[0] === 'not like') {
                    $model = $model->where($column, $value[0], "%$value[1]%");
                } elseif (in_array($value[0], ['>', '=', '<', '<>'])) {
                    $model = $model->where($column, $value[0], $value[1]);
                } elseif ($value[0] == 'in' && !empty($value[1])) {
                    $valArr = $value[1];
                    if (is_string($value[1])) {
                        $valArr = explode(",", trim($value[1]));
                    }
                    $model = $model->whereIn($column, $valArr);
                } elseif ($value[0] == 'not in' && !empty($value[1])) {
                    $valArr = $value[1];
                    if (is_string($value[1])) {
                        $valArr = explode(",", trim($value[1]));
                    }
                    $model = $model->whereNotIn($column, $valArr);
                } elseif ($value[0] == 'null') {
                    $model = $model->whereNull($column);
                } elseif ($value[0] == 'not null') {
                    $model = $model->whereNotNull($column);
                } elseif ($value[0] !== '' || $value[1] !== '') {
                    $model = $model->whereBetween($column, $value);
                }
            } else {
                $model = $model->where($column, $value);
            }
        }
        if ($field) {
            $model = $model->orderBy($field, $order);
        }
        return $model;
    }

    protected function afterQuery($items)
    {
        foreach ($items as &$item) {
            if (!empty($item['coupon_json'])) {
                $couponJson = json_decode($item['coupon_json'], true);
                if (isset($couponJson['member'])) {
                    if (isset($couponJson['member']['list']) && !empty($couponJson['member']['list'])) {
                        $item['coupon_use_member'] = 'member';
                        $item['memberList'] = $couponJson['member']['list'];
                    } else if (isset($couponJson['member']['where']) && !empty($couponJson['member']['where'])) {
                        if (trim($couponJson['member']['where']) == '1' || trim($couponJson['member']['where']) == '') {
                            $item['coupon_use_member'] = 'all';
                        } else {
                            $item['coupon_use_member'] = 'condition';
                            $where = str_replace('`', '', urldecode($couponJson['member']['where']));
                            $whereArr = explode('=', $where);
                            if (isset($whereArr[0]) && trim($whereArr[0]) == 'member_is_vip') {
                                $item['condition'] = 'is_vip';
                            } else if (isset($whereArr[0]) && trim($whereArr[0]) == 'member_classify') {
                                if (isset($whereArr[1]) && str_replace("'", '', trim($whereArr[1])) == 'MEMBER') {
                                    $item['condition'] = 'is_member';
                                } else if (isset($whereArr[1]) && str_replace("'", '', trim($whereArr[1])) == 'EMPLOY') {
                                    $item['condition'] = 'is_employ';
                                }
                            }
                        }
                    } else if (!isset($couponJson['member']['where']) || empty($couponJson['member']['where'])) {
                        $item['coupon_use_member'] = 'all';
                    }
                }
                if (isset($couponJson['premises'])) {
                    $item['premises'] = $couponJson['premises'];
                } else {
                    $item['premises_range'] = 'all';
                }
            }
            if (!empty($item['coupon_period_json'])) {
                $periodJson = json_decode($item['coupon_period_json'], true);
                $item['period'] = $periodJson['length'] ?? '';
                $item['period_unit'] = $periodJson['unit'] ?? '';
                $item['period_unit_num'] = $periodJson['val'] ?? '';
                $item['period_nbr'] = $periodJson['nbr'] ?? '';
            }
            if (!empty($item['coupon_validdate_begin']) && !empty($item['coupon_validdate_end'])) {
                $item['coupon_use_time'] = 'date';
            } elseif ($item['coupon_validdate_day']) {
                $item['coupon_use_time'] = 'day';
            }
            $item['member_count'] = 0;
            $item['pending_count'] = 0;
            $item['used_count'] = 0;
            if (!empty($item['detail'])) {
                foreach ($item['detail'] as $detail) {
                    if (!empty($detail['join_coupon_detail_member_id'])) {
                        $item['member_count'] += 1;
                    }
                    if ($detail['coupon_detail_status'] == 'PENDING') {
                        $item['pending_count'] += 1;
                    } elseif ($detail['coupon_detail_status'] == 'USED') {
                        $item['used_count'] += 1;
                    }
                }
            }
            $item['coupon_explain'] = CouponService::couponClassifyInfo($item['coupon_classify'], $item['coupon_category'], $item['coupon_value'], $item['coupon_minimum_limit']);
            unset($item['detail']);
        }

        return $items;
    }

    /**
     * @Desc 优惠券顶部统计
     * @Author Gorden
     * @Date 2024/10/31 16:36
     *
     * @param Request $request
     * @return Response
     */
    public function statistics(Request $request)
    {
        $params = $request->get();
        $coupons = Coupon::selectRaw('coupon_classify,count(coupon_id) as total')
//            ->where('coupon_status', 'ACTIVED')
            ->when(!empty($params['coupon_classify']), function ($query) use ($params) {
                $query->where('coupon_classify', $params['coupon_classify']);
            })
            ->when(!empty($params['join_coupon_category_id']), function ($query) use ($params) {
                $query->whereIn('join_coupon_category_id', $params['join_coupon_category_id']);
            })
            ->when(!empty($params['coupon_id']), function ($query) use ($params) {
                $query->where('coupon_id', 'like', '%' . trim($params['coupon_id']) . '%');
            })
            ->when(!empty($params['couponName']), function ($query) use ($params) {
                $query->where('coupon_name', 'like', '%' . trim($params['couponName']) . '%');
            })
            ->when(!empty($params['coupon_addtimes']), function ($query) use ($params) {
                $params['coupon_addtimes'][0] = strtotime($params['coupon_addtimes'][0]);
                $params['coupon_addtimes'][1] = strtotime($params['coupon_addtimes'][1]);
                $query->whereBetween('coupon_addtimes', $params['coupon_addtimes']);
            })
            ->groupBy('coupon_classify')
            ->get()
            ->toArray();
        $statistics = [];
        $statistics['total'] = 0;
        foreach ($coupons as $coupon) {
            $statistics['total'] += $coupon['total'];
            if ($coupon['coupon_classify'] == '季卡') {
                $statistics['jika'] = $coupon['total'];
            } else if ($coupon['coupon_classify'] == '年卡') {
                $statistics['nianka'] = $coupon['total'];
            } else if ($coupon['coupon_classify'] == '折扣券') {
                $statistics['zhekou'] = $coupon['total'];
            } else if ($coupon['coupon_classify'] == '抵用券') {
                $statistics['dikou'] = $coupon['total'];
            } else if ($coupon['coupon_classify'] == '月卡') {
                $statistics['yueka'] = $coupon['total'];
            } else if ($coupon['coupon_classify'] == '满减券') {
                $statistics['manjian'] = $coupon['total'];
            } else if ($coupon['coupon_classify'] == '福利券') {
                $statistics['fuli'] = $coupon['total'];
            } else if ($coupon['coupon_classify'] == '立减券') {
                $statistics['lijian'] = $coupon['total'];
            } else if ($coupon['coupon_classify'] == '赠品券') {
                $statistics['zengpin'] = $coupon['total'];
            }
        }

        // 领完的券
        $couponNumbers = Coupon::where('coupon_number', '>', 0)
            ->select('coupon_id', 'coupon_number')
            ->get()
            ->toArray();
        $statistics['done'] = 0;
        foreach ($couponNumbers as $item) {
            if (CouponDetail::where('join_detail_coupon_id', $item['coupon_id'])->whereIn('coupon_detail_status', ['IN', 'PENDING'])->count('join_detail_coupon_id') >= $item['coupon_number']) {
                $statistics['done'] += 1;
            }
        }

        return json_success('success', $statistics);
    }

    public function selectList()
    {
        $coupons = Coupon::where('coupon_status', 'ACTIVED')
            ->select('coupon_id', 'coupon_name')
            ->orderBy('coupon_addtimes', 'DESC')
            ->get()
            ->toArray();

        return json_success('', $coupons);
    }

//    public function afterQuery($items)
//    {
//        foreach ($items as &$item) {
//            $item->coupon_begindate = date('Y-m-d H:i:s', $item->coupon_begindate);
//            $item->coupon_enddate = date('Y-m-d H:i:s', $item->coupon_enddate);
//        }
//
//        return $items;
//    }

    /**
     * @Desc 添加优惠券
     * @Author Gorden
     * @Date 2024/8/14 15:16
     *
     * @param Request $request
     * @return Response
     */
    public function insert(Request $request): Response
    {
        if ($this->validate && !$this->validateClass->scene('add')->check($request->post())) {
            return json_fail($this->validateClass->getError());
        }
        $goods = $request->post('goodsContentList', []);
//        if (empty($goods)) {
//            return json_fail("请选择关联的产品");
//        }

        Db::beginTransaction();
        try {
            $data = $this->insertInput($request);
            $data['coupon_creator_user_id'] = JwtToken::getCurrentId();
            $this->doInsert($data);
            // 关联优惠券和商品、规格
            $this->insertCouponGoods($goods, $data['coupon_id']);
            if ($data['coupon_number'] > 0) {
                $this->generateCouponDetail($data['coupon_id'], $data['coupon_status'], $data['coupon_number']);
            }
            Db::commit();

            return json_success('success');
        } catch (BusinessException $customException) {
            Db::rollBack();
            dump($customException->getMessage());
            return json_fail($customException->getMessage());
        } catch (\Exception $e) {
            Db::rollBack();
            dump($e->getMessage());
            return json_fail('数据写入失败');
        }
    }

    /**
     * @Desc 关联优惠券、产品、规格
     * @Author Gorden
     * @Date 2024/8/14 14:32
     *
     * @param $goods
     * @param $couponId
     * @return void
     * @throws BusinessException
     */
    public function insertCouponGoods($goods, $couponId)
    {
        try {
            foreach ($goods as $good) {
                CouponGoods::insert([
                    'join_goods_coupon_id' => $couponId,
                    'join_coupon_goods_id' => $good['goods_id'],
                    'join_coupon_goods_sku_id' => $good['sku_id'],
                    'coupon_goods_json' => '[]',
                    'coupon_goods_extend_json' => '[]',
                    'coupon_goods_addtimes' => time()
                ]);
            }
        } catch (\Exception $e) {
            throw new BusinessException("关联产品失败");
        }
    }

    protected function insertInput(Request $request): array
    {
        $params = $request->post();
        $data = $this->inputFilter($params);
        $data['coupon_id'] = "CU" . date("ymdHi") . random_string(4, 'up');
        if (!empty($params['coupon_use_time']) && $params['coupon_use_time'] == 'date') {
            $data['coupon_validdate_day'] = 0;
            $data['coupon_validdate_begin'] = date("Y-m-d H:i:s", strtotime($data['coupon_validdate_begin']));
            $data['coupon_validdate_end'] = date("Y-m-d H:i:s", strtotime($data['coupon_validdate_end']));
        } elseif (!empty($params['coupon_use_time']) && $params['coupon_use_time'] == 'day') {
            $data['coupon_validdate_begin'] = '';
            $data['coupon_validdate_end'] = '';
        }
        $couponJson = [];
        if ($params['coupon_use_member'] == 'member' && isset($params['member_list'])) {
            $couponJson['member']['list'] = $params['member_list'];
            $couponJson['member']['range'] = '';
            $couponJson['member']['where'] = '';
        } else if ($params['coupon_use_member'] == 'condition') {
            $couponJson['member']['list'] = [];
            if (isset($params['condition']) && $params['condition'] == 'is_vip') {
                $couponJson['member']['range'] = 'VIP会员';
                $couponJson['member']['where'] = urlencode(" `member_is_vip` = 'Y'");
            } elseif (isset($params['condition']) && $params['condition'] == 'is_employ') {
                $couponJson['member']['range'] = '公司员工';
                $couponJson['member']['where'] = urlencode(" `member_classify` = 'EMPLOY'");
            } elseif (isset($params['condition']) && $params['condition'] == 'is_member') {
                $couponJson['member']['range'] = '会员';
                $couponJson['member']['where'] = urlencode(" `member_classify` = 'MEMBER'");
            }
        } else if ($params['coupon_use_member'] == 'all') {
            $couponJson['member']['list'] = [];
            $couponJson['member']['range'] = '全部会员';
            $couponJson['member']['where'] = '';
        }

        if (!empty($params['premises_range']) && $params['premises_range'] == 'all') {
            $couponJson['premises_range'] = '所有门店可用';
        } elseif (!empty($params['premises_range']) && $params['premises_range'] == 'part') {
            $couponJson['premises'] = $params['premises'];
            $couponJson['premises_range'] = '部分门店可用';
        }

        if (in_array($data['coupon_classify'], ['抵用券', '立减券', '赠品券', '福利券', '年卡', '季卡', '月卡'])) {
            $data['coupon_minimum_limit'] = 0;
        }

        $data['coupon_json'] = json_encode($couponJson, JSON_UNESCAPED_UNICODE);

        // 处理周期优惠券
        if ($params['coupon_is_period'] != 'N') {
//            $this->disposePeriod($params);
            $data['coupon_period_json'] = json_encode([
                'length' => $params['period'],
                'unit' => $params['period_unit'],
                'val' => $params['period_unit_num'],
                'nbr' => $params['period_nbr']
            ]);
        }

        return $data;
    }

    public function disposePeriod($params)
    {
        if (empty($params['period']) || empty($params['period_unit']) || empty($params['period_unit_num']) || empty($params['period_nbr'])) {
            throw new BusinessException("周期数据异常");
        }

        if ($params['period'] != 'TO_EXPIRE') {
            return $params;
        }
//        if (empty($params['coupon_validdate_end'])) {
//            throw new BusinessException("周期数据异常");
//        }
        try {
            $endTimeUnix = strtotime($params['coupon_validdate_end']);
            if ($params['period_unit'] == 'day') {
                $diff = ceil(($endTimeUnix - time()) / (3600 * 24));
            } else if ($params['period_unit'] == 'week') {
                $diff = ceil(($endTimeUnix - time()) / (3600 * 24));
                $diff = ceil($diff / 7);
            } else if ($params['period_unit'] == 'month') {
                $endTime = new \DateTime($params['coupon_validdate_end']);
                $nowTime = new \DateTime(date('Y-m-d'));
                $interval = $nowTime->diff($endTime);
                $diff = $interval->y * 12 + $interval->m + 1;
            }

            if ($params['period_nbr'] != ceil($diff / $params['period_unit_num'])) {
                throw new BusinessException("期数设置错误");
            }

            return $params;
        } catch (\Exception $e) {

            throw new BusinessException($e->getMessage());
        }
    }

    public function customSend(Request $request)
    {
        $chooseCoupons = $request->post('chooseCoupons', []);
        $couponUseMember = $request->post('coupon_use_member', '');
        $memberList = $request->post('member_list', []);
        $condition = $request->post('condition', '');
        if ($couponUseMember == 'condition') {
            if ($condition == 'is_employ') {
                $memberList = Member::where('member_classify', 'EMPLOY')->pluck('member_id')->toArray();
            } elseif ($condition == 'is_member') {
                $memberList = Member::where('member_classify', 'MEMBER')->pluck('member_id')->toArray();
            } elseif ($condition == 'is_vip') {
                $memberList = Member::where('member_is_vip', 'Y')->pluck('member_id')->toArray();
            }
        }

        $couponNbr = [];
        Db::beginTransaction();
        try {
            $couponIds = array_column($chooseCoupons, 'id');
            $coupons = Coupon::whereIn('coupon_id', $couponIds)->get()->toArray();
            foreach ($coupons as $coupon) {
                foreach ($chooseCoupons as $chooseCoupon) {
                    if ($chooseCoupon['id'] == $coupon['coupon_id']) {
                        if (empty($chooseCoupon['gain_datetime'])) {
                            $chooseCoupon['gain_datetime'] = date('Y-m-d H:i:s');
                        }
                        $params['coupon_id'] = $coupon['coupon_id'];
                        $params['coupon_detail_gain_datetime'] = date('Y-m-d H:i:s', strtotime($chooseCoupon['gain_datetime']));
                        if (($coupon['coupon_validdate_day'] == 0 || $coupon['coupon_validdate_day'] == '') && !empty($coupon['coupon_validdate_end'])) {
                            $params['coupon_detail_deadline_datetime'] = $coupon['coupon_validdate_end'];
                        } elseif ($coupon['coupon_validdate_day'] > 0) {
                            $endUnix = strtotime($chooseCoupon['gain_datetime']);
                            $params['coupon_detail_deadline_datetime'] = date('Y-m-d H:i:s', $endUnix + ($coupon['coupon_validdate_day'] * 24 * 3600) - 1);
                        }
                        foreach ($memberList as $item) {
                            $params['member_id'] = $item;
                            if ($coupon['coupon_is_period'] == 'Y') {
//                                if (CouponDetail::where('join_coupon_detail_member_id', $item)->where('join_detail_coupon_id', $coupon['coupon_id'])->exists()) {
//                                    throw new BusinessException("请勿重复发放周期券");
//                                }
                                $params['coupon_detail_period_num'] = 1;
                                $periodJson = json_decode($coupon['coupon_period_json'], true);
//                                for ($i=0;$i<$periodJson['nbr'];$i++){
                                CouponDetailService::sendPeriodCoupon($params);
//                                }

                                continue;
                            }
                            if ($chooseCoupon['nbr'] > 0) {
                                $params['chooseCouponNbr'] = $chooseCoupon['nbr'];
                                // 有发行数量
                                if ($coupon['coupon_number'] != 0) {
                                    // 查询还有多少张没领的
                                    $count = CouponDetail::where('join_detail_coupon_id', $coupon['coupon_id'])
                                        ->whereIn('coupon_detail_status', ['INIT', 'PENDING'])
                                        ->count();
                                    if (!isset($couponNbr[$coupon['coupon_id']])) {
                                        $couponNbr[$coupon['coupon_id']] = $count;
                                    }
                                    if ($couponNbr[$coupon['coupon_id']] - $chooseCoupon['nbr'] < 0) {
                                        Log::error("优惠券发放失败，超出发行数量", $params);
                                        throw new BusinessException($coupon['coupon_name'] . "超出发行数量");
                                    }
                                    $couponNbr[$coupon['coupon_id']] = $couponNbr[$coupon['coupon_id']] - $chooseCoupon['nbr'];
                                    // 匹配已发行的优惠券
                                    CouponDetailService::customSendCouponHave($params);
                                } else {
                                    for ($i = 0; $i < $chooseCoupon['nbr']; $i++) {
                                        CouponDetailService::customSendCoupon($params);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            Db::commit();
            return json_success("发放成功");
        } catch (BusinessException $e) {
            Db::rollBack();
            return json_fail($e->getMessage());
        } catch (\Exception $e) {
            dump($e->getTrace());
            Db::rollBack();
            return json_fail('优惠券发放失败');

        }

    }

    /**
     * @Desc 修改优惠券
     * @Author Gorden
     * @Date 2024/8/14 15:48
     *
     * @param Request $request
     * @return Response
     */
    public function update(Request $request): Response
    {
        if ($this->validate && !$this->validateClass->scene('update')->check($request->post())) {
            return json_fail($this->validateClass->getError());
        }

        $params = $request->post();

        Db::beginTransaction();
        try {
            [$id, $data] = $this->updateInput($request);
            $originCouponNumber = $data['origin_coupon_number'];
            $originCouponValiddateDay = $data['origin_coupon_validdate_day'];
            $originCouponValiddateEnd = $data['origin_coupon_validdate_end'];
            unset($data['origin_coupon_number'], $data['origin_coupon_validdate_day'], $data['origin_coupon_validdate_end']);
            $this->updateCouponGoods($request->post('goodsContentList'), $id);
            if ($originCouponNumber == 0 && $data['coupon_number'] != 0) {
                // 查已领取多少了
                $detailCount = CouponDetail::where('join_detail_coupon_id', $id)->count();
                if ($detailCount < $data['coupon_number']) {
                    $this->generateCouponDetail($id, $data['coupon_status'], $data['coupon_number'] - $detailCount);
                }
            } else if ($originCouponNumber < $data['coupon_number']) {
                $this->generateCouponDetail($id, $data['coupon_status'], $data['coupon_number'] - $originCouponNumber);
            } else if ($originCouponNumber > $data['coupon_number']) {
                CouponDetail::where('join_detail_coupon_id', $id)
                    ->where('join_coupon_detail_member_id', '')
                    ->limit($originCouponNumber - $data['coupon_number'])
                    ->delete();
            }
            // 修改时间了
            if ($params['coupon_use_time'] == 'day' && $originCouponValiddateDay != $data['coupon_validdate_day']) {
                $this->updateDetailTimeForDay($id, $data['coupon_validdate_day']);
            } elseif ($params['coupon_use_time'] == 'date' && $originCouponValiddateEnd != $data['coupon_validdate_end']) {
                $this->updateDetailTimeForDate($id, $data['coupon_validdate_end']);
            }


            // 激活状态,初始改为待领取
            if ($data['coupon_status'] == 'ACTIVED') {
                CouponDetail::where('join_detail_coupon_id', $id)->where('coupon_detail_status', 'INIT')->update(['coupon_detail_status' => 'PENDING']);
            } elseif ($data['coupon_status'] == 'DISABLED') {   // 禁用状态，未领取未使用的都是禁用
                CouponDetail::where('join_detail_coupon_id', $id)->where('coupon_detail_status', '<>', 'USED')->update(['coupon_detail_status' => 'DISABLED']);
            }

            $this->doUpdate($id, $data);

            Db::commit();

            return json_success('success');
        } catch (BusinessException $e) {
            Db::rollBack();
            return json_fail($e->getMessage());
        } catch (\Exception $e) {
            Db::rollBack();
            dump($e->getMessage());
            return json_fail('数据更新失败');
        }

    }

    public function updateDetailTimeForDay($couponId, $day)
    {
        $details = CouponDetail::where('join_detail_coupon_id', $couponId)
            ->where('coupon_detail_status', '<>', 'USED')
            ->where('coupon_detail_deadline_datetime', '<>', '')
            ->get()
            ->toArray();

        try {
            foreach ($details as $detail) {
                $couponDetailGainDatetime = strtotime($detail['coupon_detail_gain_datetime']);
                CouponDetail::where('coupon_detail_id', $detail['coupon_detail_id'])
                    ->update([
                        'coupon_detail_deadline_datetime' => date('Y-m-d H:i:s', $couponDetailGainDatetime + ($day * 24 * 3600))
                    ]);
            }
        } catch (\Exception $e) {
            dump($e->getMessage());
            throw new BusinessException("优惠券更新失败");
        }
    }

    public function updateDetailTimeForDate($couponId, $endDate)
    {
        $details = CouponDetail::where('join_detail_coupon_id', $couponId)
            ->where('coupon_detail_status', '<>', 'USED')
            ->where('coupon_detail_deadline_datetime', '<>', '')
            ->get()
            ->toArray();

        try {
            foreach ($details as $detail) {
                CouponDetail::where('coupon_detail_id', $detail['coupon_detail_id'])
                    ->update([
                        'coupon_detail_deadline_datetime' => $endDate
                    ]);
            }
        } catch (\Exception $e) {
            dump($e->getMessage());
            throw new BusinessException("优惠券更新失败");
        }
    }

    public function updateCouponGoods($goods, $couponId)
    {
        try {
            $couponGoodsIds = CouponGoods::where('join_goods_coupon_id', $couponId)->pluck('join_coupon_goods_id')->toArray();
            $goodsIds = array_column($goods, 'goods_id');
            // 新的差集
            $goodsDiff = array_diff($goodsIds, $couponGoodsIds);
            // 旧的差集
            $couponDiff = array_diff($couponGoodsIds, $goodsIds);
            foreach ($goods as $good) {
                // 更新两个中都有的
                if (in_array($good['goods_id'], $couponGoodsIds)) {
                    CouponGoods::where('join_goods_coupon_id', $couponId)->where('join_coupon_goods_id', $good['goods_id'])->update(['join_coupon_goods_sku_id' => $good['sku_id']]);
                } elseif (in_array($good['goods_id'], $goodsDiff)) {       // 新加的
                    CouponGoods::insert([
                        'join_goods_coupon_id' => $couponId,
                        'join_coupon_goods_id' => $good['goods_id'],
                        'join_coupon_goods_sku_id' => $good['sku_id'],
                        'coupon_goods_json' => '[]',
                        'coupon_goods_extend_json' => '[]',
                        'coupon_goods_addtimes' => time()
                    ]);
                }
            }
            if (!empty($couponDiff)) {   // 去掉的
                foreach ($couponDiff as $item) {
                    CouponGoods::where('join_goods_coupon_id', $couponId)->where('join_coupon_goods_id', $item)->delete();
                }
            }
        } catch (\Exception $e) {
            throw new BusinessException('关联产品更新失败');
        }
    }

    protected function updateInput(Request $request): array
    {
        $params = $request->post();
        $primary_key = $this->model->getKeyName();
        $id = $request->post($primary_key);
        $data = $this->inputFilter($params);
        if (!empty($params['coupon_use_time']) && $params['coupon_use_time'] == 'date') {
            $data['coupon_validdate_day'] = 0;
            $data['coupon_validdate_begin'] = date("Y-m-d H:i:s", strtotime($data['coupon_validdate_begin']));
            $data['coupon_validdate_end'] = date("Y-m-d H:i:s", strtotime($data['coupon_validdate_end']));
        } elseif (!empty($params['coupon_use_time']) && $params['coupon_use_time'] == 'day') {
            $data['coupon_validdate_begin'] = '';
            $data['coupon_validdate_end'] = '';
        }
        $model = $this->model->find($id);
        // 原数量
        $data['origin_coupon_number'] = $model->coupon_number;
        // 原优惠天数
        $data['origin_coupon_validdate_day'] = $model->coupon_validdate_day;
        // 原结束时间
        $data['origin_coupon_validdate_end'] = $model->coupon_validdate_end;
        if (!$model) {
            throw new BusinessException('记录不存在', 2);
        }
        $couponJson = [];
        if (!empty($model->coupon_json)) {
            $couponJson = json_decode($model->coupon_json, true);
        }
        if ($params['coupon_use_member'] == 'member' && isset($params['member_list'])) {
            $couponJson['member']['list'] = $params['member_list'];
//            if (isset($couponJson['member']['range'])) {
            $couponJson['member']['range'] = '';
//            }
//            if (isset($couponJson['member']['where'])) {
            $couponJson['member']['where'] = '';
//            }
        } else if ($params['coupon_use_member'] == 'condition') {
            if (isset($params['condition']) && $params['condition'] == 'is_vip') {
                $couponJson['member']['range'] = 'VIP会员';
                $couponJson['member']['where'] = urlencode(" `member_is_vip` = 'Y'");
            } elseif (isset($params['condition']) && $params['condition'] == 'is_employ') {
                $couponJson['member']['range'] = '公司员工';
                $couponJson['member']['where'] = urlencode(" `member_classify` = 'EMPLOY'");
            } elseif (isset($params['condition']) && $params['condition'] == 'is_member') {
                $couponJson['member']['range'] = '会员';
                $couponJson['member']['where'] = urlencode(" `member_classify` = 'MEMBER'");
            }
//            if (isset($couponJson['member']['list'])) {
            $couponJson['member']['list'] = [];
//            }
        } else if ($params['coupon_use_member'] == 'all') {
            $couponJson['member']['list'] = [];
            $couponJson['member']['range'] = '全部会员';
            $couponJson['member']['where'] = '';

            if (isset($couponJson['member']['list'])) {
                $couponJson['member']['list'] = [];
            }
        }

        if (!empty($params['premises_range']) && $params['premises_range'] == 'all') {
            $couponJson['premises_range'] = '所有门店可用';
            unset($couponJson['premises']);
        } elseif (!empty($params['premises_range']) && $params['premises_range'] == 'part') {
            $couponJson['premises'] = $params['premises'];
            $couponJson['premises_range'] = '部分门店可用';
        }
        if (empty($data['coupon_validdate_day'])) {
            $data['coupon_validdate_day'] = 0;
        }

        $data['coupon_json'] = json_encode($couponJson, JSON_UNESCAPED_UNICODE);

        $data['coupon_period_json'] = '[]';
        // 处理周期优惠券
        if ($params['coupon_is_period'] != 'N') {
            $this->disposePeriod($params);
            $data['coupon_period_json'] = json_encode([
                'length' => $params['period'],
                'unit' => $params['period_unit'],
                'val' => $params['period_unit_num'],
                'nbr' => $params['period_nbr']
            ]);
        }
        if (in_array($data['coupon_classify'], ['抵用券', '立减券', '赠品券', '福利券', '年卡', '季卡', '月卡'])) {
            $data['coupon_minimum_limit'] = 0;
        }

        unset($data[$primary_key]);
        return [$id, $data];
    }

    /**
     * 优惠券详情
     */
    public function info(Request $request): Response
    {
        try {
            $couponId = $request->get('coupon_id', '');
            if (!$couponId) {
                return json_fail('参数异常');
            }
            $coupon = Coupon::where('coupon_id', $couponId)->first();
            if (!$coupon) {
                return json_fail('数据异常');
            }
            // 拼选择的商品
            $couponGoods = CouponGoods::with([
                'goods' => function ($query) {
                    $query->select('goods_id', 'goods_id as id', 'goods_name as name', 'join_goods_category_id as pid', 'goods_classify', 'goods_sales_price', 'goods_cover');
                },
                'skus' => function ($query) {
                    $query->select('goods_sku_id', 'join_sku_goods_id', 'goods_sku_specs_json', 'goods_sku_sales_price');
                },
                'sku'
            ])->where('join_goods_coupon_id', $couponId)
                ->get()
                ->toArray();
            $goodsIds = [];
            $goodsContent = [];
            foreach ($couponGoods as $couponGood) {
                $goodsIds[] = $couponGood['join_coupon_goods_id'];
                $content = [
                    'goods_id' => $couponGood['join_coupon_goods_id'],
                    'sku_id' => $couponGood['join_coupon_goods_sku_id'],
                ];
                if (isset($couponGood['goods'])) {
                    $content['goods_name'] = $couponGood['goods']['name'];
                    $content['goods_classify'] = $couponGood['goods']['goods_classify'];
                    $content['goods_cover'] = getenv('STORAGE_DOMAIN') . $couponGood['goods']['goods_cover'];
                }
                if (isset($couponGood['sku']) && isset($couponGood['sku']['goods_sku_specs_json'])) {
//                $skuSpecsJson = json_decode($couponGood['sku']['goods_sku_specs_json'], true);
//                $skuName = '';
//                foreach ($skuSpecsJson as $item) {
//                    if (is_array($item)) {
//                        $item = implode('', $item);
//                    }
//                    $skuName .= $item . '，';
//                }
//                $content['sku_name'] = rtrim($skuName, '，');
                    $content['goods_sales_price'] = $couponGood['sku']['goods_sku_sales_price'];
                }
                if (isset($couponGood['skus'])) {
                    foreach ($couponGood['skus'] as $key => $skus) {
                        if (!empty($skus['goods_sku_specs_json'])) {
                            $skuSpecsJson = json_decode($skus['goods_sku_specs_json'], true);
                            $skuName = '';
                            foreach ($skuSpecsJson as $item) {
                                if (is_array($item)) {
                                    $item = implode('', $item);
                                }
                                $skuName .= $item . ',';
                            }
                            $couponGood['skus'][$key]['sku_name'] = rtrim($skuName, ',');
                        }
                    }
                    $content['skus'] = $couponGood['skus'];
                }
                $goodsContent[] = $content;
            }
            // 选中的会员
            $memberLists = [];
            // 可用门店
            $premises = [];
            if (!empty($coupon->coupon_json)) {
                $couponJson = json_decode($coupon->coupon_json, true);
                if (isset($couponJson['member']) && isset($couponJson['member']['list']) && !empty($couponJson['member']['list'])) {
                    $res = Db::table('member')
                        ->leftjoin('member_cert', 'member.member_id', '=', 'member_cert.join_cert_member_id')
                        ->leftjoin('member_info', 'member.member_id', '=', 'member_info.join_info_member_id')
                        ->select('member.member_id', 'member.member_mobile', 'member_cert.member_cert_name', 'member_info.member_info_nickname')
                        ->where('member_status', 'ACTIVED')
                        ->whereIn('member_id', $couponJson['member']['list'])
                        ->get();
                    $memberLists = [];
                    foreach ($res as $item) {
                        $name = '';
                        if (!empty($item->member_cert_name)) {
                            $name = $item->member_cert_name;
                        } else if (!empty($item->member_info_nickname)) {
                            $name = $item->member_info_nickname;
                        }
                        $value = !empty($name) ? $name . '-' : '';
                        if ($item->member_mobile != '0000') {
                            $value .= $item->member_mobile;
                        }
                        if (empty($value)) {
                            $value = $item->member_mobile;
                        }
                        $value = rtrim($value, '-');
                        $memberLists[] = [
                            'key' => $item->member_id,
                            'value' => $value,
                        ];
                    }
                }
                if (isset($couponJson['premises']) && !empty($couponJson['premises'])) {
                    $premises = SysDept::whereIn('dept_id', $couponJson['premises'])
                        ->select('dept_id', 'dept_name')
                        ->get()
                        ->toArray();
                }
            }

            $data = [
                'goods_ids' => $goodsIds,
                'goods_content' => $goodsContent,
                'member_lists' => $memberLists,
                'premises_list' => $premises
            ];

            Log::info("查询优惠券详情成功");
            return json_success('', $data);

        } catch (\Exception $e) {
            Log::error("查询优惠券详情失败", ['msg' => $e->getMessage()]);
            return json_fail('查询失败');
        }
    }

    /**
     * 删除
     * @param Request $request
     * @return Response
     * @throws BusinessException
     */
    public function delete(Request $request): Response
    {
        $ids = $this->deleteInput($request);
        Db::beginTransaction();
        try {
            // 删除优惠券关联的产品
            foreach ($ids as $id) {
                $couponDetail = CouponDetail::with([
                    'coupon' => function ($query) {
                        $query->select('coupon_id', 'coupon_name');
                    }
                ])->where('join_detail_coupon_id', $id)
                    ->where('join_coupon_detail_member_id', '<>', '')
                    ->first();
                if (!empty($couponDetail)) {
                    Db::rollBack();

                    return json_fail($couponDetail->coupon && $couponDetail->coupon->coupon_name ? $couponDetail->coupon->coupon_name . "已被领取，无法删除，请禁用" : "删除的优惠券中有已被领取的，无法删除，请禁用");
                }
                CouponGoods::where('join_goods_coupon_id', $id)->delete();

                CouponDetail::where('join_detail_coupon_id', $id)->delete();
            }
            $this->doDelete($ids);
            Db::commit();
            return json_success('success');
        } catch (\Exception $e) {
            dump($e->getMessage());
            Db::rollBack();
            return json_fail('删除失败');
        }
    }

    public function disableCoupon(Request $request)
    {
        $couponId = $request->post('coupon_id');
        if (!$couponId) {
            return json_fail("参数异常");
        }
        Db::beginTransaction();
        try {
            Coupon::where('coupon_id', $couponId)->update(['coupon_status' => 'DISABLED']);
            CouponDetail::where('join_detail_coupon_id', $couponId)->whereIn('coupon_detail_status', ['INIT', 'PENDING'])->update(['coupon_detail_status' => 'DISABLED']);
            Db::commit();
            return json_success('success');
        } catch (\Exception $e) {
            Db::rollBack();
            return json_fail("禁用失败");
        }
    }

    private function generateCouponDetail($couponId, $couponStatus, $nbr)
    {
        for ($i = 0; $i < intval($nbr); $i++) {
            $insertData = [
                'coupon_detail_id' => 'CUDT' . date("ymdHi") . random_string(4, 'up'),
                'join_detail_coupon_id' => $couponId,
                'coupon_detail_status' => $couponStatus == 'ACTIVED' ? 'PENDING' : 'INIT',
                'coupon_detail_addtimes' => time()
            ];
            try {
                CouponDetail::insert($insertData);
            } catch (\Exception $e) {
                $insertData['coupon_detail_id'] = $insertData['coupon_detail_id'] . random_string(1, 'up');
                CouponDetail::insert($insertData);
            }
        }
    }
}