<?php
namespace app\api\logic;
use app\common\logic\BaseLogic;
use app\common\model\coupon\CouponCategory;
use app\common\model\coupon\CouponGoods;
use app\common\model\coupon\CouponRules;
use app\common\model\coupon\UserCoupon;
use app\common\model\goods\Goods;
use think\db\Query;
use think\db\Where;
use think\Exception;
use think\facade\Db;
use think\facade\Log;

/**
 * @author 林海涛
 * @date 2024/7/18 下午4:49
 */
class UserCouponLogic extends BaseLogic
{
    public static function add($params)
    {
        Db::startTrans();
        try{
            $errMsgArr = [];
            $rules = CouponRules::whereIn('code',$params['codes'])->where('voucher_status',1)->lock(true)->select();
            $userCoupon = UserCoupon::where('user_id',$params['user_id'])
                ->whereIn('code',$params['codes'])
                ->where('voucher_count','>',0)
                ->select();

            if($rules->isEmpty()){
                $errMsgArr[] = '优惠券不存在';
            }
            $updateData = [];
            $createData = [];
            foreach($rules as $v) {
                if($v->voucher_status == 2){
                    $errMsgArr[] = $v->event_name .'已设置为过期';
                    continue;
                }
                if($v->remaining_count <= 0 ){
                    $errMsgArr[] = $v->event_name .'数量不足';
                    continue;
                }
                if(isset($params['property_activity_id']) && !empty($params['property_activity_id'])){
                    if($userCoupon->where('coupon_id',$v->id)->where('property_activity_id',$params['property_activity_id'])->count()){
                        $errMsgArr[] = $v->event_name . '活动券已经领取过了，请勿重复领取';
                        continue;
                    }
                }else{
                    if($userCoupon->where('coupon_id',$v->id)->where('property_activity_id',0)->count()){
                        $errMsgArr[] = $v->event_name . '已经领取过了，请勿重复领取';
                        continue;
                    }
                }
                $updateData[$v->id] = ['remaining_count' => --$v->remaining_count];
                $createData[] = [
                    'user_id'=>$params['user_id'],
                    'coupon_target'=>$v->coupon_target,
                    'coupon_id' => $v->id,
                    'code' => $v->code,
                    'voucher_status' => 0,
                    'voucher_count' =>1,
                    'amount' => $v->mold_type != 1 ? $v->amount:null,
                    'amount_require' => $v->amount_require,
                    'begin_use' => time(),
                    'discount_ratio' =>  $v->mold_type == 1 ? $v->discount_ratio:null,
                    'event_name' => $v->event_name,
                    'expire_time' => time()+$v->expire_time,
                    'max_deductible_price' => $v->mold_type == 1 ? $v->max_deductible_price:null,
                    'mold_type' => $v->mold_type,
                    'server_category_name' => $v->server_category_name,
                    'property_activity_id' => $params['property_activity_id']??0,
                ];
            }
            if(!empty($updateData)){
                CouponRules::updateWhenCase($updateData);
            }
            if(!empty($createData)){
                (new UserCoupon())->saveAll($createData);
            }
            Db::commit();
            return $errMsgArr;
        }catch(\Exception $e){
            Db::rollback();
            self::setError($e->getMessage());
            return false;
        }

    }

    /**
     * 我的优惠卷列表
     * @param $params
     * @return array|false
     */
    public static function userCouponList($params)
    {
        try{
            $where = [];
            $where[] = ['voucher_status','=',0];
            if(isset($params['voucher_status']) && is_array($params['voucher_status'])){
                $where[] = ['voucher_status','IN',$params['voucher_status']];
            }
            $where[] = ['user_id','=',$params['user_id']];

            $data = UserCoupon::where($where)
                ->where(function(Query $query){
                    $query->where(' expire_time >'. time());
                })
                ->field(['id','code','amount','amount_require','begin_use','voucher_status','discount_ratio','event_name','expire_time','max_deductible_price','server_category_name','mold_type'])
                ->append(['voucher_status_text','discount_ratio_text'])
                ->order(['id' => 'desc'])
                ->select()
                ->toArray();
            $couponCodes = [];
            foreach($data as $k => $v){
                if($v['expire_time'] < time()){
                    $couponCodes[] = $v['code'];
                    $data[$k]['voucher_status_text'] = '已过期';
                }
                $data[$k]['begin_use'] = date("Y-m-d H:i:s",$v['begin_use'] );
                $data[$k]['expire_time'] = date("Y-m-d H:i:s",$v['expire_time'] );
                $data[$k]['amount_require'] = '满'.$v['amount_require'].'可用';
            }
            if(!empty($couponCodes)){
                UserCoupon::whereIn('code',$couponCodes)->update(['voucher_status'=>2]);
            }
            return $data;
        } catch (\Exception $e){
            Db::rollback();
            self::setError($e->getMessage());
            return false;
        }
    }

    /**
     * 商品分类优惠卷领取
     * @param $params
     * @return array|false
    */
    public static function categoryCouponLists($params)
    {
        try{
            $coupon_ids = CouponCategory::where('goods_category_id',$params['goods_category_id'])->column('coupon_id');

            $data =  CouponRules::where('remaining_count','>',0)
                ->where('coupon_type',1)
                ->whereIn('id',$coupon_ids)
                ->where('voucher_status',1)
                ->append(['discount_ratio_text'])
                ->order(['id' => 'desc'])
                ->field(['code','amount','amount_require','discount_ratio','server_category_name',
                    'event_name','expire_time','max_deductible_price','mold_type',])
                ->select();
            foreach($data as $k => $v){
                $data[$k]['amount_require'] = '满'.$v['amount_require'].'可用';
            }
            $codes = $data->column('code');
            $userCouponCodes = [];
            if(!empty($code)){
                $userCouponCodes = UserCoupon::where('code',$codes)
                    ->where('user_id',$params['user_id'])->column('code');
            }
            $data = $data->whereNotIn('code',$userCouponCodes)->toArray();
            return $data;
        }catch(\Exception $e){
            self::setError($e->getMessage());
            return false;
        }
    }

    public static function categoryWithAmountLists($params)
    {
        Log::info('coupon-'.json_encode($params));
        try{
            // 构建查询条件
            $query = UserCoupon::where('user_id', $params['user_id'])
                ->where('voucher_count', '>', 0)
                ->where('voucher_status', 0)
                ->where('expire_time', '>', time())
                ->where('amount_require', '<=', $params['amount']);
            // 执行查询并获取结果集
            $coupons = $query->select()->toArray(); // 使用 toArray() 获取数组形式的结果
            $filteredCoupons = array_filter($coupons, function ($item) use ($params) {
                if ($item['coupon_target'] == 'category') {
                    $coupon_id = CouponCategory::where('coupon_id', $item['coupon_id'])
                        ->where('goods_category_id', $params['goods_category_id'])
                        ->value('coupon_id'); // 获取单个值
                } elseif ($item['coupon_target'] == 'goods') {
                    $coupon_id = CouponGoods::where('coupon_id', $item['coupon_id'])
                        ->where('goods_id', $params['goods_id'])
                        ->value('coupon_id'); // 获取单个值
                }
                // 如果 $coupon_id 不为空，则保留该项
                return !empty($coupon_id);
            });

            // 提取所有 coupon_id 到数组
            $coupon_ids = array_column($filteredCoupons, 'coupon_id');

            $data = UserCoupon::where('user_id',$params['user_id'])
                ->where('voucher_count','>',0)
                ->where('voucher_status',0)
                ->whereIn('coupon_id',$coupon_ids);
                // 去除代理券
                if(isset($params['property_activity_id']) && !empty($params['property_activity_id'])){
                    $remove_user_coupon_ids = UserCoupon::where('property_activity_id',$params['property_activity_id'])->column('id')?:[];
                    !empty($remove_user_coupon_ids) && $data = $data->whereNotIn('id',$remove_user_coupon_ids);
                    Log::info('remove_coupon_ids-1001:'.json_encode([$params['property_activity_id'],$remove_user_coupon_ids]));
                }elseif (isset($params['goods_id']) && !empty($params['goods_id'])){
                    $remove_coupon_ids = [];
                    $property_activity_id = Goods::where('id',$params['goods_id'])->value('property_activity_id');
                    $property_activity_id && $remove_coupon_ids = CouponRules::where('property_activity_id',$property_activity_id)->column('id')?:[];
                    !empty($remove_coupon_ids) && $data = $data->whereNotIn('coupon_id',$remove_coupon_ids);
                    Log::info('remove_coupon_ids-1001:'.json_encode([$params['goods_id'],$property_activity_id,$remove_coupon_ids]));
                }
            $data = $data->append(['discount_ratio_text'])
                ->where('expire_time','>',time())
                ->visible(['id','coupon_id','amount','amount_require','begin_use','discount_ratio','event_name','expire_time','max_deductible_price','server_category_name','mold_type'])
                ->order('amount desc')
                ->select()
                ->each(function (&$item){
                    $item['begin_use'] = date("Y-m-d H:i:s",$item['begin_use'] );
                    $item['expire_time'] = date("Y-m-d H:i:s",$item['expire_time'] );
                    $item['amount_require'] = '满'.$item['amount_require'].'可用';
                })
                ->toArray();
            return $data;
        } catch(\Exception $e){
            self::setError($e->getMessage());
            return false;
        }
    }
}