<?php

namespace App\Http\Controllers\Api\Customers;

use App\Common\Enums\HtTab;
use App\Exceptions\Api\ApiException;
use App\Http\Controllers\LoginController;

use App\Modules\Enums\ErrorCode;
use App\Modules\Enums\SuccessCode;
use App\Modules\Models\Production\Production;
use App\Modules\Models\Rent\Rent;
use App\Repositories\Customers\MachineRepository;
use App\Repositories\Customers\RentRepository;
use App\Repositories\Customers\WeChatRepository;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;

/**
 * Class RentController
 * @package App\Http\Controllers\Api
 */
class RentController extends LoginController
{
    /**
     * @var RentRepository
     */
    protected $rent;
    /**
     * @var MachineRepository
     */
    protected $machine;


    protected $weChat;

    /**
     * RentController constructor.
     * @param RentRepository $rent
     */
    public function __construct(RentRepository $rent, MachineRepository $machine, WeChatRepository $weChat)
    {
        parent::__construct();
        $this->rent = $rent;
        $this->machine = $machine;
        $this->weChat = $weChat;

    }

    function scan(Request $request)
    {
        Log::info("[scan] params:" . json_encode($request->all()));

        $country_id = $request->get('country_id') ? $request->get('country_id') : 1;

        $machine_info = $this->machine->rentInfo($request->get('mac_no'), $country_id);
        $response = [
            'machine' => $machine_info,
        ];
        $result = $this->rent->checkOrder($this->user->id);

        switch ($result['status']) {
            case 1:
                $response['success_code'] = SuccessCode::NEED_TO_RENT;
                $response['success_mes'] = trans('api.success.need_to_rent');
                break;
            case 2:
                throw new ApiException(ErrorCode::RENT_ORDER_NOT_BACK, trans('api.error.rent_order_not_back'));
                break;
            case 3:
                $response['success_code'] = SuccessCode::NEED_TO_TAKE;
                $response['rent_no'] = $result['rent_no'];
                $response['success_mes'] = trans('api.success.need_to_take');
                break;
            default:
                break;
        }
        return $this->responseSuccess($response);
    }

    function checkOrderStatus(Request $request)
    {
        Log::info("[checkOrderStatus] params:" . json_encode($request->all()));

        $rent_obj = $this->rent->getRentOutDetail($request->get('rent_no'));
        //发货流程是否已经处理完
        $response['is_over'] = 0;
        if ($rent_obj->take_time) {
            if (strtotime($rent_obj->take_time) - strtotime() > 60) {
                $response['is_over'] = 1;
            }
        }

        $out = $this->rent->getOutHatchs($rent_obj);
        $response['success_hatch_nos'] = $out['success_hatch_nos'];
        $response['fail_hatch_nos'] = $out['fail_hatch_nos'];
        if (!$out['fail_hatch_nos']) {
            $response['success_code'] = SuccessCode::RENT_OUT_OVER;
            $response['success_mes'] = trans('api.success.rent_out_over');
            $response['is_over'] = 1;
        } else {
            $response['success_code'] = SuccessCode::RENT_OUT_NOT_OVER;
            $response['success_mes'] = trans('api.success.rent_out_not_over');
        }
        return $this->responseSuccess($response);
    }

    function makeOrder(Request $request)
    {
        Log::info("[makeOrder] params:" . json_encode($request->all()));

        $data = $request->only('mac_no', 'number');

        if($request->has('powerType')){
            $data['powerType'] = $request->input('powerType');
        }else{
            $data['powerType'] = 'E2';
        }

        //查找是否有订单未完结
        $result = $this->rent->checkOrder($this->user->id);
        switch ($result['status']) {
            case 2:
                throw new ApiException(ErrorCode::RENT_ORDER_NOT_BACK, trans('api.error.rent_order_not_back'));
                break;
            case 3:
                throw new ApiException(ErrorCode::RENT_ORDER_NOT_BACK, trans('api.error.rent_order_not_take'));
                break;
            default:
                break;
        }
        //生成订单
        $rent_order = $this->rent->makeOrder($data, $this->user->id, 1);
        //微信小程序支付
        $pay_res = $this->weChat->submitOrderToWeChat(1, $rent_order, $this->user->mini_program_open_id);


        return $this->responseSuccess($pay_res);
    }


    function detail(Request $request)
    {
        Log::info("[detail] params:" . json_encode($request->all()));

        $rent_no = $request->get('rent_no');
        $rent_info_obj = $this->rent->getRentInfo($rent_no);
        $res = $this->formatRentInfo($rent_info_obj);
        return $this->responseSuccess($res);
    }

    function orderStatus(Request $request)
    {
        Log::info("[orderStatus] params:" . json_encode($request->all()));
        $rent_no = $request->get('rent_no');
        $rent_info_obj = $this->rent->getRent($rent_no);
        $res = $this->formatOrderStatusInfo($rent_info_obj);
        return $this->responseSuccess($res);
    }


    function subscribeScan(Request $request)
    {
        Log::info("[subscribeScan] params:" . json_encode($request->all()));
        $machine_info = $this->machine->rentInfo($request->get('mac_no'));
        $result = $this->rent->checkOrder($this->user->id);
        $response = [
            'machine' => $machine_info,
        ];
        switch ($result['status']) {
            case 1:
                $response['success_code'] = SuccessCode::NEED_TO_RENT;
                $response['success_mes'] = trans('api.success.need_to_rent');
                break;
            case 2:
                $response['success_code'] = SuccessCode::RENT_ORDER_NOT_BACK;
                $response['rent_no'] = $result['rent_no'];
                $response['success_mes'] = trans('api.success.rent_order_not_back');
                break;
            default:
                $response['success_code'] = SuccessCode::NEED_TO_TAKE;
                $response['rent_no'] = $result['rent_no'];
                $response['success_mes'] = trans('api.success.need_to_take');
                break;
        }
        return $this->responseSuccess($response);

    }


    function makeSubscribeOrder(Request $request)
    {
        Log::info("[makeSubscribeOrder] params:" . json_encode($request->all()));

        $data = $request->only('mac_no', 'number');
        //查找是否有订单未完结
        $result = $this->rent->checkOrder($this->user->id);
        switch ($result['status']) {
            case 2:
                throw new ApiException(ErrorCode::RENT_ORDER_NOT_BACK, trans('api.error.rent_order_not_back'));
                break;
            case 3:
                throw new ApiException(ErrorCode::NEED_TO_TAKE, trans('api.error.rent_order_not_take'));
                break;
            default:
                break;
        }
        //生成订单
        $rent_order = $this->rent->makeOrder($data, $this->user->id, 2);
        //微信小程序支付
        $pay_res = $this->weChat->submitOrderToWeChat(1, $rent_order, $this->user->mini_program_open_id);
        return $this->responseSuccess($pay_res);
    }

    function check(Request $request)
    {
        Log::info("[check] params:" . json_encode($request->all()));

        $rent_obj = $this->rent->getRent($request->get('rent_no'));
        if (!$rent_obj->is_pay) {
            throw new ApiException(ErrorCode::RENT_HAS_NOT_PAY, trans('api.error.rent_has_not_pay'));
        }
        if ($rent_obj->is_cancel) {
            $response['success_code'] = SuccessCode::SUBSCRIBE_FAIL;
            $response['success_mes'] = trans('api.success.subscribe_fail');
        } else {
            $response['success_code'] = SuccessCode::SUBSCRIBE_SUCCESS;
            $response['success_mes'] = trans('api.success.subscribe_success');
        }
        return $this->responseSuccess($response);
    }

    function take(Request $request)
    {

        Log::info("[take] params:" . json_encode($request->all()));

        //验证
        $need_take = $this->rent->getNotOverRentByNO($request->get('rent_no'));
        if ($need_take == null) {
            throw new ApiException(ErrorCode::RENT_ORDER_ILLEGAL_TAKE, trans('api.error.rent_order_illegal_take'));
        }
        if ($need_take->is_take) {
            throw new ApiException(ErrorCode::RENT_ORDER_ILLEGAL_TAKE, trans('api.error.rent_order_illegal_take'));
        }
        //取货
        $res = $this->rent->doTake($need_take);
        $response = [];
        if ($res['status'] == 2) {
            $response['success_code'] = SuccessCode::MACHINE_IN_USE;
            $response['success_mes'] = trans('api.success.machine_in_use');
        } elseif ($res['status'] == 1) {
            $response['success_code'] = SuccessCode::TAKE_SUCCESS;
            $response['success_mes'] = trans('api.success.take_success');
        }
        return $this->responseSuccess($response);
    }

    function myRecord(Request $request)
    {
        Log::info("[myRecord] params:" . json_encode($request->all()));

        $data = $request->only('page', 'limit');
        $data['page'] = isset($data['page']) ? $data['page'] : 0;
        $data['limit'] = isset($data['limit']) ? $data['limit'] : HtTab::DEFAULT_LIMIT;
        $rent_obj = $this->rent->getMyRecord($this->user->id, $data['page'], $data['limit']);
        $response = $this->formatRentRecord($rent_obj);
        return $this->responseSuccess($response);
    }

    function myRecordDetail(Request $request)
    {
        Log::info("[myRecordDetail] params:" . json_encode($request->all()));

        $rent_no = $request->get('rent_no');
        $rent_info_obj = $this->rent->getRentInfo($rent_no);
        $res = $this->formatMyRecordRentInfo($rent_info_obj);
        return $this->responseSuccess($res);
    }

    function subscribeStatus()
    {
        $rent_obj = $this->rent->getNotOverRent($this->user->id);
        if ($rent_obj == null) {
            $response['success_code'] = SuccessCode::NO_SUBSCRIBE;
            $response['success_mes'] = trans('api.success.no_subscribe');
            return $this->responseSuccess($response);
        }
        if ($rent_obj->is_take == 1) {
            $response['success_code'] = SuccessCode::HAS_TAKE;
            $response['success_mes'] = trans('api.success.has_take');
            return $this->responseSuccess($response);
        }
        $rent_product_spot_obj = $rent_obj->with(['spot', 'production'])->where('rent_no', $rent_obj->rent_no)->first();
        $response['data'] = $this->formatRentInfo($rent_product_spot_obj);
        $response['success_code'] = SuccessCode::NEED_TO_TAKE;
        $response['success_mes'] = trans('api.success.need_to_take');
        return $this->responseSuccess($response);

    }


    function packageRent(Request $request)
    {
        Log::info("[packageRent] params:" . json_encode($request->all()));
        $data = $request->only('page', 'limit');
        $data['page'] = isset($data['page']) ? $data['page'] : 0;
        $data['limit'] = isset($data['limit']) ? $data['limit'] : HtTab::DEFAULT_LIMIT;
        $rent_obj = $this->rent->getMyRecord($this->user->id, $data['page'], $data['limit']);
        $response = $this->formatPackageRentRecord($rent_obj);
        return $this->responseSuccess($response);
    }

    function formatOrderStatusInfo($rent_obj)
    {
        $data = [
            'is_over' => $rent_obj->is_over
        ];
        return $data;
    }

    function formatRentInfo($rent_obj)
    {
        $hatch_nos = [];
        if ($rent_obj->production) {
            foreach ($rent_obj->production as $production_obj) {
                $hatch_nos [] = $production_obj->rent_hatch_no;

            }
        }
        $data = [
            'spot_name' => $rent_obj->spot->spotname,
            'spot_code' => $rent_obj->spot->code,
            'pay_time' => $rent_obj->pay_time,
            'total' => $rent_obj->deposit * $rent_obj->number,
            'number' => $rent_obj->number,
            'hatch_nos' => $hatch_nos,
            'rent_no' => $rent_obj->rent_no,

        ];
        return $data;
    }


    function formatMyRecordRentInfo($rent_obj)
    {

        $data = [
            'recharge' => $rent_obj->deposit * $rent_obj->number,
            'rent_time' => $rent_obj->pay_time,
            'rent_no' => $rent_obj->rent_no,
            'rent_address' => $rent_obj->spot->spotname,
        ];

        if ($rent_obj->production) {
            foreach ($rent_obj->production as $k => $production_obj) {
                $data['production'][$k]['hatch_no'] = $production_obj->rent_hatch_no;
                $data['production'][$k]['status'] = $this->rent->getProductionStatus($production_obj);
                if ($data['production'][$k]['status'] == 1) {
                    $fee = $this->rent->checkFee($rent_obj->pay_time, $production_obj->return_time, $rent_obj->one_day_price, $rent_obj->free_time);
                    $data['production'][$k]['use_time'] = $fee['use_m'];
                    $data['production'][$k]['rent_money'] = $production_obj->total;
                    $data['production'][$k]['back_money'] = $rent_obj->deposit - $production_obj->total;
                }

            }
        }

        if ($rent_obj->is_over) {
            $discount_money = $rent_obj->total - $rent_obj->real_total;
            if ($discount_money) {
                $num = count($rent_obj->production) - 1;
                $data['production'][$num]['discount_money'] = $discount_money;
                $data['production'][$num]['back_money'] += $discount_money;
            }

        }

        return $data;
    }


    function formatRentRecord($rents_obj)
    {
        $data = [];
        foreach ($rents_obj as $key => $rent_obj) {
            $data[$key]['rent_no'] = $rent_obj->rent_no;
            $data[$key]['total'] = $rent_obj->deposit * $rent_obj->number;
            $data[$key]['rent_time'] = $rent_obj->pay_time;
            $data[$key]['number'] = $rent_obj->number;
            $data[$key]['address'] = $rent_obj->spot->spotname;
            $data[$key]['status'] = $this->rent->getRentStatus($rent_obj);
        }

        return ['list' => $data];

    }

    function formatPackageRentRecord($rents_obj)
    {
        $data = [];
        foreach ($rents_obj as $key => $rent_obj) {
            $data[$key]['rent_no'] = $rent_obj->rent_no;
            $data[$key]['recharge'] = $rent_obj->deposit * $rent_obj->number;
            $data[$key]['back_money'] = $rent_obj->back_money;
            $data[$key]['real_total'] = $rent_obj->real_total;
            $data[$key]['rent_time'] = $rent_obj->pay_time;
            $data[$key]['address'] = $rent_obj->spot->spotname;
            $data[$key]['status'] = $this->rent->getRentStatus($rent_obj);
        }

        return ['list' => $data];
    }


}