<?php
/**
 *  ╔═══════════════════════════════════════════════════╗
 *  ║                                                   ║
 *  ║     ██╗  ██╗   █████╗    ██████╗                  ║
 *  ║     ██║  ██║  ██╔══██╗  ██╔═══██╗                 ║
 *  ║     ███████║  ███████║  ██║   ██║                 ║
 *  ║     ██╔══██║  ██╔══██║  ██║   ██║                 ║
 *  ║     ██║  ██║  ██║  ██║  ╚██████╔╝   SNS           ║
 *  ║                                                   ║    
 *  ║                                                   ║    
 *  ║     © 2023 HaoSNS™ All Rights Reserved            ║
 *  ║     官方网站: https://www.haosns.com                *
 *  ║     本代码由赣州乐易网络科技有限公司®提供             *
 *  ║                                                    *
 *  ║   未经授权禁止复制、传播或用于其他商业目的            *
 *  ║                                                   ║
 *  ╚═══════════════════════════════════════════════════╝
 */

namespace app\api\controller\twoshop;

// use app\common\service\after_sale\AfterSaleService;
use app\api\logic\twoshop\AfterSaleLogic;
use app\api\validate\twoshop\AfterSaleValidate;
use app\common\enum\AfterSaleEnum;
use app\common\enum\AfterSaleLogEnum;
use app\common\enum\OrderEnum;
use app\common\logic\TwoRefundLogic;
use app\common\model\Region;
use app\common\model\TwoAfterSale;
use app\common\model\TwoAfterSaleGoods;
use app\common\model\TwoOrder;
use app\common\model\UserAddress;
use app\common\service\twoshop\AfterSaleService;
use think\facade\Db;
use think\Validate;

/**
 * 售后控制器
 * Class AfterSaleController
 * @package app\api\controller
 */
class AfterSale extends \app\api\controller\BaseShopController
{
    /**
     * @notes 子订单商品信息
     * @return \think\response\Json
     */
    public function orderGoodsInfo()
    {
        // $params = (new AfterSaleValidate())->goCheck('orderGoodsInfo');
        // $result = AfterSaleLogic::orderGoodsInfo($params);
        // return $this->data($result);
    }

    /**
     * @notes 卖家同意售后
     * @return \think\response\Json
     */
    public function agree()
    {
        $params = $this->request->post();

        Db::startTrans();
        try{
            $afterSale = \app\common\model\TwoAfterSale::with("order")
            ->find(data: $params['id']);

             if($afterSale->isEmpty()) {
                throw new \think\Exception('售后订单不存在');
             }

            // dd($afterSale->order->sell_user_id);
            // dd($this->userId);
            if($this->userId != $afterSale->order->sell_user_id){
                throw new \think\Exception('非卖家无权限操作此订单');
            }
           
            if($afterSale->status != 1) {
                throw new \think\Exception('不在售后中状态,不能进行同意售后操作');
            }
            if($afterSale->sub_status != 11) {
                throw new \think\Exception('不是等待卖家同意状态,不能进行同意售后操作');
            }
            // dd($afterSale->refund_method);
            // refund_method 退款方式 1-仅退款 2-退货退款
            // `sub_status` tinyint(2) unsigned NOT NULL COMMENT '售后子状态：11-售后中，等待卖家同意；12-售后中，卖家已同意，等待买家发货；13-售后中，买家已发货，等待卖家收货；14-售后中，卖家已收货，等待卖家处理；15-售后中，卖家已同意，等待退款；16-售后中，售后退款中；17-售后中，售后退款失败，等待卖家处理；21-售后成功，售后退款成功；31-售后失败，买家取消售后；32-售后失败，卖家拒绝售后；33-售后失败，卖家拒绝收货；34-售后失败，卖家拒绝退款',
            switch($afterSale->refund_method) {
                // 仅退款
                case 1:
                    $afterSale->sub_status = 15;
                    \app\common\service\twoshop\AfterSaleService::createAfterLog($afterSale->id, '卖家已同意,等待退款', $this->userId, 3);
                    break;
                // 退货退款
                case 2:
                    $afterSale->address_id = $params['address_id'] ?? null;
                    $afterSale->sub_status = 12;
                    \app\common\service\twoshop\AfterSaleService::createAfterLog($afterSale->id, '卖家已同意售后,等待买家退货', $this->userId, 3);
                    break;
            }
            
            $afterSale->admin_id = $this->userId;//操作者id
            $afterSale->admin_remark = $params['admin_remark'] ?? '';
            $afterSale->save();

            Db::commit();
            return show(config('status.success'),'操作成功');
        } catch(\Exception $e) {
            Db::rollback();
            // self::setError($e->getMessage());
            return show(config('status.error'),$e->getMessage());
        }
    }

    public function del()
    {
        $params = $this->request->post();
        $res=\app\common\model\TwoAfterSale::where('user_id', $this->userId)->where('id', $params['id'])->find();
        if(!$res) {
            return show(config('status.error'),'删除失败,售后订单不存在或不属于你');
        }
        $res->delete();
        return show(config('status.success'),'删除成功');
    }

    /**
     * @notes 卖家拒绝售后
     * @return \think\response\Json
     */
    public function refuse()
    {
        $params = $this->request->post();

        Db::startTrans();
        try{
            $afterSale = \app\common\model\TwoAfterSale::findOrEmpty($params['id']);
            if($afterSale->isEmpty()) {
                throw new \think\Exception('售后订单不存在');
            }

            if($this->userId != $afterSale->order->sell_user_id){
                throw new \think\Exception('非卖家无权限操作此订单');
            }
            if($afterSale->status != 1) {
                throw new \think\Exception('不在售后中状态,不能进行拒绝售后操作');
            }
            if($afterSale->sub_status != 11) {
                throw new \think\Exception('不是等待卖家同意状态,不能进行拒绝售后操作');
            }
            $afterSale->status = 3; // 售后失败
            $afterSale->sub_status = 32;//32-售后失败，卖家拒绝售后
            $afterSale->admin_id = $this->userId;
            $afterSale->admin_remark = $params['admin_remark'] ?? '';
            $afterSale->save();

            \app\common\service\twoshop\AfterSaleService::createAfterLog($afterSale->id, '卖家拒绝售后', $this->userId, 3);

            // 消息通知
            event('Notice', [
                'scene_id' => 108,
                'params' => [
                    'user_id' => $afterSale->user_id,
                    'after_sale_sn' => $afterSale->sn
                ]
            ]);

            Db::commit();
            return show(config('status.success'),'操作成功');
        } catch(\Exception $e) {
            Db::rollback();
            // self::setError($e->getMessage());
            // return false;
            return show(config('status.error'),$e->getMessage());
        }
    }
    
    /**
     * @notes 申请商品售后
     * @return \think\response\Json
     */
    public function apply()
    {
        $params = (new AfterSaleValidate())->post()->goCheck('apply');
        $params['user_id'] = $this->userId;
        $result = AfterSaleLogic::apply($params);
        if($result === false) {
            return $this->fail(AfterSaleLogic::getError());
        }
        return $this->success('申请商品售后成功', $result);
    }

    /**
     * @notes 买家取消售后
     * @return \think\response\Json
     */
    public function cancel()
    {
         $params = (new AfterSaleValidate())->post()->goCheck('cancel');
         $params['user_id'] = $this->userId;
         $result = AfterSaleLogic::cancel($params);
         if($result) {
             return $this->success('买家取消售后成功');
         }
         return $this->fail(AfterSaleLogic::getError());
    }

    /**
     * @notes 买家确认退货
     * @return \think\response\Json
     */
    public function returnGoods()
    {
         $params = (new AfterSaleValidate())->post()->goCheck('returnGoods');
         $params['user_id'] = $this->userId;
         $result = AfterSaleLogic::returnGoods($params);
         if($result) {
             return $this->success('买家确认退货');
         }
         return $this->fail(AfterSaleLogic::getError());
    }

    /**
     * @notes 查看售后列表
     * @return \think\response\Json
     */
    public function lists()
    {
         $params = (new AfterSaleValidate())->goCheck('lists');
         $params['user_id'] = $this->userId;
         $params['page_no'] = $params['page_no'] ?? 1;
         $params['page_size'] = $params['page_size'] ?? 25;
         $result = AfterSaleLogic::lists($params);
         return $this->data($result);
    }

    /**
     * @notes 查看售后详情
     * @return \think\response\Json
     */
    public function detail()
    {
         $params = (new AfterSaleValidate())->goCheck('detail');
         $result = AfterSaleLogic::detail($params);
         return $this->data($result);
    }

    public function listBuy()
    {
        $params = $this->request->post();
        $where = [];

        switch($params['type'] ?? 'all') {
            case 'status_ing':
                $status = [AfterSaleEnum::STATUS_ING];
                break;
            case 'status_success':
                $status = [AfterSaleEnum::STATUS_SUCCESS];
                break;
            case 'status_fail':
                $status = [AfterSaleEnum::STATUS_FAIL];
                break;
            case 'status_success_fail':
                $status = [AfterSaleEnum::STATUS_SUCCESS, AfterSaleEnum::STATUS_FAIL];
                break;
        }

        if (isset($status)) {
            $where[] = ['status', 'in', $status];
        }

        $data = TwoAfterSale::with(['user'=>function($query) {
            $query->field('id,nickname,avatar');
        }, 'order', 'orderGoods'])
            ->where('user_id', $this->userId)->where($where)
            ->select();

        return show(1, '买家售后列表', $data);
    }

    public function buyDetail($id)
    {
        $data = TwoAfterSale::with(['user'=>function($query) {
            $query->field('id,nickname,avatar');
        }, 'order', 'orderGoods'])
            ->where('user_id', $this->userId)->where('id', $id)
            ->find();

        $address = UserAddress::find($data['address_id']);

        if (!$address) {
            $address = UserAddress::where('user_id', $data['user_id'])->where('is_default', 1)->find();
        }

        if ($address) {
            $data['return_contact'] = $address['contact'];
            $data['return_contact_mobile'] = $address['mobile'];
            $data['return_province_id'] = $address['province_id'];
            $data['return_province'] = Region::where('id', $address['province_id'])->value('name');
            $data['return_city_id'] = $address['city_id'];
            $data['return_city'] = Region::where('id', $address['city_id'])->value('name');
            $data['return_district_id'] = $address['district_id'];
            $data['return_district'] = Region::where('id', $address['district_id'])->value('name');
            $data['return_address'] = $address['address'];
        } else {
            $data['return_contact'] = null;
            $data['return_contact_mobile'] = null;
            $data['return_province_id'] = null;
            $data['return_province'] = null;
            $data['return_city_id'] = null;
            $data['return_city'] = null;
            $data['return_district_id'] = null;
            $data['return_district'] = null;
            $data['return_address'] = null;
        }

        if (!$data) {
            return show(0, '查询失败');
        }
        return show(1, '成功', $data);
    }

    public function refuseExpress()
    {
        $params = $this->request->post();
        Db::startTrans();
        try {
            $afterSale = TwoAfterSale::findOrEmpty($params['id']);
            if($afterSale->isEmpty()) {
                throw new \think\Exception('售后单不存在');
            }
            if($afterSale->status != AfterSaleEnum::STATUS_ING) {
                throw new \think\Exception('不是售后中状态，不能进行拒绝收货操作');
            }
            if($afterSale->sub_status != AfterSaleEnum::SUB_STATUS_WAIT_SELLER_RECEIPT) {
                throw new \think\Exception('不是等待卖家收货状态，不允许进行拒绝收货操作');
            }
            $afterSale->status = AfterSaleEnum::STATUS_FAIL;
            $afterSale->sub_status = AfterSaleEnum::SUB_STATUS_SELLER_REFUSE_RECEIPT;
            $afterSale->save();

            // 记录日志
            AfterSaleService::createAfterLog($afterSale->id, '卖家拒绝收货，售后失败', $this->userId, AfterSaleLogEnum::ROLE_SELLER);

            Db::commit();
            return show(1, '成功');
        } catch(\Exception $e) {
            Db::rollback();
            return show(0,$e->getMessage());
        }
    }

    public function confirmExpress()
    {
        $params = $this->request->post();
        Db::startTrans();
        try {
            $afterSale = TwoAfterSale::findOrEmpty($params['id']);
            if($afterSale->isEmpty()) {
                throw new \think\Exception('售后单不存在');
            }
            if($afterSale->status != AfterSaleEnum::STATUS_ING) {
                throw new \think\Exception('不是售后中状态，不能进行确认收货操作');
            }
            if($afterSale->sub_status != AfterSaleEnum::SUB_STATUS_WAIT_SELLER_RECEIPT) {
                throw new \think\Exception('不是等待卖家收货状态，不允许进行确认收货操作');
            }
            $afterSale->sub_status = AfterSaleEnum::SUB_STATUS_WAIT_SELLER_HANDLE;
            $afterSale->save();

            // 记录日志
            AfterSaleService::createAfterLog($afterSale->id, '卖家确认收货，等待卖家处理', $this->userId, AfterSaleLogEnum::ROLE_SELLER);

            Db::commit();
            return show(1,'成功');
        } catch(\Exception $e) {
            Db::rollback();
            return show(0,$e->getMessage());
        }
    }

    public function agreeRefund()
    {
        $params = $this->request->post();
        Db::startTrans();
        try {
            $afterSale = TwoAfterSale::findOrEmpty($params['id']);
            if($afterSale->isEmpty()) {
                throw new \think\Exception('售后单不存在');
            }
            if($afterSale->status != AfterSaleEnum::STATUS_ING) {
                throw new \think\Exception('不是售后中状态，不能进行同意退款操作');
            }
            if($afterSale->sub_status != AfterSaleEnum::SUB_STATUS_WAIT_SELLER_HANDLE) {
                throw new \think\Exception('不是等待卖家处理状态，不允许进行同意退款操作');
            }
            $afterSale->sub_status = AfterSaleEnum::SUB_STATUS_WAIT_SELLER_REFUND;
            $afterSale->save();

            // 记录日志
            AfterSaleService::createAfterLog($afterSale->id, '卖家已同意，等待退款', $this->userId, AfterSaleLogEnum::ROLE_SELLER);

            Db::commit();
            return show(1,'成功');
        } catch(\Exception $e) {
            Db::rollback();
            return show(0,$e->getMessage());
        }
    }

    public function refuseRefund()
    {
        $params = $this->request->post();
        Db::startTrans();
        try {
            $afterSale = TwoAfterSale::findOrEmpty($params['id']);
            if($afterSale->isEmpty()) {
                throw new \think\Exception('售后单不存在');
            }
            if($afterSale->status != AfterSaleEnum::STATUS_ING) {
                throw new \think\Exception('不是售后中状态，不能进行拒绝退款操作');
            }
            if($afterSale->sub_status != AfterSaleEnum::SUB_STATUS_WAIT_SELLER_HANDLE) {
                throw new \think\Exception('不是等待卖家处理状态，不允许进行拒绝退款操作');
            }
            $afterSale->status = AfterSaleEnum::STATUS_FAIL;
            $afterSale->sub_status = AfterSaleEnum::SUB_STATUS_SELLER_REFUSE_REFUND;
            $afterSale->save();

            // 记录日志
            $order = TwoOrder::findOrEmpty($afterSale->order_id);
            $order->order_status = OrderEnum::STATUS_FINISH;
            $order->save();

            AfterSaleService::createAfterLog($afterSale->id, '卖家拒绝退款,售后失败', $this->userId, AfterSaleLogEnum::ROLE_SELLER);

            Db::commit();
            return show(1,'成功');
        } catch(\Exception $e) {
            Db::rollback();
            return show(0,$e->getMessage());
        }
    }

    public function confirmRefund()
    {
        $params = $this->request->post();
        Db::startTrans();
        try {
            $params['refund_total_amount'] = floatval($params['refund_total_amount']);
            $afterSale = TwoAfterSale::findOrEmpty($params['id']);
            if($afterSale->isEmpty()) {
                throw new \think\Exception('售后单不存在');
            }
            if($afterSale->status != AfterSaleEnum::STATUS_ING) {
                throw new \think\Exception('不是售后中状态，不能进行确认退款操作');
            }
            if($afterSale->sub_status != AfterSaleEnum::SUB_STATUS_WAIT_SELLER_REFUND) {
                throw new \think\Exception('不是等待卖家退款状态，不允许进行确认退款操作');
            }
            if($afterSale->refund_total_amount < $params['refund_total_amount']) {
                throw new \think\Exception('退款金额不能大于订单实付金额');
            }

            $afterSale->refund_total_amount = $params['refund_total_amount'];
            $afterSale->refund_way = $params['refund_way'];
            $afterSale->sub_status = AfterSaleEnum::SUB_STATUS_SELLER_REFUND_ING;
            $afterSale->save();

            // 更新售后商品记录中的退款金额
            TwoAfterSaleGoods::where('after_sale_id', $afterSale->id)->update(['refund_amount' => $params['refund_total_amount']]);

            // 记录日志
            AfterSaleService::createAfterLog($afterSale->id, '卖家已确认退款，售后退款中', $this->userId, AfterSaleLogEnum::ROLE_SELLER);

            // 退款
            $order = TwoOrder::findOrEmpty($afterSale->order_id);
            $order->order_status = OrderEnum::STATUS_FINISH;
            $order->save();

            TwoRefundLogic::refund($afterSale->refund_way, $order->toArray(), $afterSale->id, $afterSale->refund_total_amount);

            Db::commit();
            return show(1,'成功');
        } catch (\Exception $e) {
            Db::rollback();
            return show(0,$e->getMessage());
        }
    }
}