<?php

namespace App\Repositories\Customers;

use App\Common\Enums\HtTab;
use App\Exceptions\Api\ApiException;

use App\Exceptions\Handler;
use App\Modules\Enums\ErrorCode;
use App\Modules\Models\GuideRecord\GuideRecord;
use App\Modules\Models\Receive\Receive;
use App\Modules\Models\Share\Share;
use App\Modules\Models\Spot\Spot;
use App\Modules\Models\WxGuide\WxGuide;
use App\Modules\Repositories\BaseRepository;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;


/**
 * Class EloquentHistoryRepository.
 */
class WeGuideRepository extends BaseRepository
{

    public function getWeGuideRule($spot_code)
    {
        $spot = Spot::with('guideRule')->where('code', $spot_code)->first();
        if (!$spot) {
            throw new ApiException(ErrorCode::SPOT_NOT_EXIST, trans('api.error.spot_not_exist'));
        }
        if ($spot->guide_rule == null) {
            throw new ApiException(ErrorCode::GUIDE_RULE_NOT_EXIST, trans('api.error.guide_rule_not_set'));
        }
        return $spot->toArray();

    }

    function getLastShare($spot_id, $customer_id)
    {
        $where = [
            [
                'spot_id', '=', $spot_id
            ],
            [
                'customer_id', '=', $customer_id
            ]

        ];
        $share = Share::where($where)->orderBy('id', 'desc')->first();
        if ($share == null) {
            throw new ApiException(ErrorCode::SHARE_NOT_EXIST, trans('api.error.share_not_exist'));
        }
        return $share->order_no;
    }

    public function isOwn($spot_id, $customer_id)
    {
        $key = HtTab::GUIDE_PERMISSION . '_' . $spot_id . '_' . $customer_id;
        return Redis::get($key);
    }

    public function guideDataformat($spot_info)
    {
        $data = [
            'spot_name' => $spot_info['spotname'],
            'open_time' => $spot_info['time'],
            'over_time' => $spot_info['overtime'],
            'guide_fee' => $spot_info['guide_rule']['guide_fee'],
            'description' => $spot_info['guide_rule']['description'],
            'own_time' => $spot_info['guide_rule']['own_time'],
        ];

        return $data;
    }


    public function makeOrder($spot_code, $customer_id)
    {

        $guide_rule = $this->getWeGuideRule($spot_code);
        if ($this->isOwn($guide_rule['id'], $customer_id)) {
            throw new ApiException(ErrorCode::GUIDE_HAS_BUY, trans('api.error.guide_has_buy'));
        }
        $data = [
            'guide_no' => $this->createOrderNo(),
            'total' => $guide_rule['guide_rule']['guide_fee'],
            'real_total' => $guide_rule['guide_rule']['guide_fee'],
            'add_time' => date('Y-m-d H:i:s'),
            'own_time' => $guide_rule['guide_rule']['own_time'],
            'customer_id' => $customer_id,
            'spot_id' => $guide_rule['id'],
            'business_id' => $guide_rule['business_id'],
        ];
        return $this->createGuideRecord($data);

    }


    public function createGuideRecord($data)
    {
        return GuideRecord::create($data);
    }

    /**
     * 生成订单单号
     */
    function createOrderNo()
    {
        return HtTab::GUIDE_ORDER . date('Ymd') . str_pad(mt_rand(1, 9999999999), 10, '0', STR_PAD_LEFT);
    }

    /**
     * 购买微导览成功后业务逻辑
     * @param $guide_no
     * @return bool
     * @throws ApiException
     */


    function paySuccess($guide_no)
    {
        $where = [
            [
                'guide_no', '=', $guide_no
            ],
            [
                'is_pay', '=', 0
            ],
        ];
        $guide = GuideRecord::where($where)->first();
        if ($guide == null) {
            throw new ApiException(ErrorCode::GUIDE_RECORD_NOT_EXIST, trans('api.error.guide_record_not_exist'));
        }
        //发放微导览服务
        $this->provideGuideService($guide->customer_id, $guide->spot_id, $guide->own_time, $guide_no);
        //结束订单
        $this->overGuideRecord($guide);
        //设置分享权限
        $this->provideShareService($guide, 2);
        return true;

    }

    function provideGuideService($customer_id, $spot_id, $own_time, $guide_no)
    {
        $time = 24 * 60 * 60 * $own_time;
        Redis::setex(HtTab::GUIDE_PERMISSION . '_' . $spot_id . '_' . $customer_id, $time, $guide_no);

    }

    function provideShareService($order_obj, $type)
    {
        switch ($type) {
            case 1:
                $data = [
                    'order_no' => $order_obj->rent_no,
                    'order_id' => $order_obj->id,
                    'type' => 1,
                    'spot_id' => $order_obj->spot_id,
                    'business_id' => $order_obj->business_id,
                    'customer_id' => $order_obj->customer_id,
                ];
                break;
            case 2:
                $data = [
                    'order_no' => $order_obj->guide_no,
                    'order_id' => $order_obj->id,
                    'type' => 2,
                    'spot_id' => $order_obj->spot_id,
                    'business_id' => $order_obj->business_id,
                    'customer_id' => $order_obj->customer_id,
                ];
                break;
        }
        $this->insertShare($data);
    }

    function insertShare($data)
    {
        $share = new Share();
        foreach ($data as $k => $v) {
            $share->$k = $v;
        }
        $share->save();
    }

    function overGuideRecord($guide)
    {
        $guide->is_pay = 1;
        $guide->pay_time = date('Y-m-d H:i:s');
        DB::beginTransaction();
        try {
            $guide->save();
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            throw new ApiException(ErrorCode::DATABASE_ERROR, trans('api.error.database_error'));
        }

    }

    function getOrderShare($order_no)
    {
        $where = [
            ['order_no', '=', $order_no],
        ];
        $share = Share::where($where)->first();
        if ($share == null) {
            throw new ApiException(ErrorCode::SHARE_NO_EXIST, trans('api.error.share_no_exist'));
        }
        return $share;
    }

    function getReceiveUser($share_obj)
    {
        $users = $share_obj->customer()->get()->toArray();
        return ['users' => $users];

    }

    /**
     * 查看分享的领取状态
     * @param $share
     * @param $customer_id
     * @return int
     */


    function getReceiveStatus($share, $customer_id)
    {
        if ($share->customer_id = $customer_id) {
            return 5;
        }
        $where = [
            [
                'share_id', '=', $share->id
            ]
        ];
        $own = $this->isOwn($share->spot_id, $customer_id);
        $receive = Receive::where($where)->get()->toArray();
        $is_reveive = $this->isReceive($receive,$customer_id);
        if ($own && $is_reveive) {
          return 1;
        } elseif(!$is_reveive && $own ){
            return 6;
        }elseif($is_reveive && !$own ){
            return 2;
        }
        if (count($receive) >= 3) {
            return 3;
        }
        return 4;
    }

    function isReceive($receive,$customer_id){
        foreach ($receive as $value) {
            if ($value['customer_id'] == $customer_id) {
               return true;
            }
        }
        return false;
    }

    function setGuideReceive($share_id, $spot_id, $customer_id, $order_no)
    {
        $this->setReceiveRecord($share_id, $customer_id);
        $this->provideGuideService($customer_id, $spot_id, 3, $order_no);
        return true;
    }

    function setReceiveRecord($share_id, $customer_id)
    {
        $data = [
            'share_id' => $share_id,
            'customer_id' => $customer_id,
        ];
        try {
            Receive::create($data);
        } catch (\Exception $e) {
            DB::rollBack();
            throw new ApiException(ErrorCode::DATABASE_ERROR, trans('api.error.database_error'));
        }
    }


    function getMyRecord($customer_id, $page, $limit)
    {
        $where = [
            ['customer_id', '=', $customer_id],
            ['is_pay', '=', 1],
        ];
        $guide_records_obj = GuideRecord::where($where)->orderBy('pay_time','desc')->skip($page * $limit)->take($limit)->with(['spot'])->get();
        $data = [];
        foreach ($guide_records_obj as $key => $guide_record_obj) {


            $data[$key]['address'] = $guide_record_obj->spot->spotname;
            $data[$key]['guide_no'] = $guide_record_obj->guide_no;

            $data[$key]['total'] = $guide_record_obj->total;
            $data[$key]['real_total'] = $guide_record_obj->real_total;

            $data[$key]['pay_time'] = $guide_record_obj->pay_time;
        }
        return ['list' => $data];
    }


}
