<?php

namespace App\Http\Controllers\Client;

use App\Http\Controllers\Controller;
use App\Services\Client\OrderService;
use Illuminate\Http\Request;

class OrderController extends Controller
{
    protected OrderService $service;

    public function __construct(OrderService $service)
    {
        $this->service = $service;
    }

    /**
     * 订单初始化
     */
    public function initialize(Request $request)
    {
        $userId = Auth::id();
        $coachId = $request->input('coach_id');
        $areaCode = $request->input('area_code');
        $projectId = $request->input('project_id');
        
        return $this->service->initialize($userId, $coachId, $areaCode, $projectId);
    }

    /**
     * 结束订单
     */
    public function finish(Request $request)
    {
        $userId = Auth::id();
        $orderId = $request->input('order_id');
        
        return $this->service->finishOrder($userId, $orderId);
    }

    /**
     * 确认技师离开
     */
    public function confirmLeave(Request $request) 
    {
        $userId = Auth::id();
        $orderId = $request->input('order_id');
        
        return $this->service->confirmLeave($userId, $orderId);
    }

    /**
     * 取消订单
     */
    public function cancel(Request $request)
    {
        $userId = Auth::id();
        $orderId = $request->input('order_id');
        
        return $this->service->cancelOrder($userId, $orderId);
    }

    /**
     * 获取订单列表
     */
    public function list()
    {
        return $this->service->getOrderList();
    }

    /**
     * 获取订单详情
     */
    public function detail($id)
    {
        return $this->service->getOrderDetail($id);
    }

    /**
     * 订单退款
     */
    public function refund($id)
    {
        return $this->service->refundOrder($id);
    }

    /**
     * 获取代理商配置
     */
    public function getAgentConfig(Request $request)
    {
        $agentId = $request->input('agent_id');
        return $this->service->getAgentConfig($agentId);
    }

    /**
     * 获取技师配置
     */
    public function getCoachConfig(Request $request)
    {
        $coachId = $request->input('coach_id');
        return $this->service->getCoachConfig($coachId);
    }

    /**
     * 计算路费金额
     */
    public function calculateDeliveryFee(Request $request)
    {
        $coachId = $request->input('coach_id');
        $agentId = $request->input('agent_id');
        $distance = $request->input('distance');
        $latitude = $request->input('latitude');
        $longitude = $request->input('longitude');

        if ($agentId) {
            return $this->service->calculateDeliveryFee($coachId, $agentId, $distance);
        } else {
            return $this->service->calculateDeliveryFeeByLocation($coachId, $latitude, $longitude, $distance);
        }
    }

    /**
     * 计算订单金额
     */
    public function calculateOrderAmount(Request $request)
    {
        $userId = Auth::id();
        $addressId = $request->input('address_id');
        $coachId = $request->input('coach_id');
        $projectId = $request->input('project_id');
        $agentId = $request->input('agent_id');
        $useBalance = $request->input('use_balance', 0);

        return $this->service->calculateOrderAmount($userId, $addressId, $coachId, $projectId, $agentId, $useBalance);
    }

    /**
     * 创建订单
     */
    public function create(Request $request)
    {
        $userId = Auth::id();
        $projectId = $request->input('project_id');
        $addressId = $request->input('address_id');
        $coachId = $request->input('coach_id');
        $useBalance = $request->input('use_balance', 0);
        $orderId = $request->input('order_id');

        return $this->service->createOrder($userId, $projectId, $addressId, $coachId, $useBalance, $orderId);
    }

    /**
     * 加钟
     */
    public function addTime(Request $request, $orderId)
    {
        $userId = Auth::id();
        return $this->service->addTime($userId, $orderId);
    }

    /**
     * 指定技师
     */
    public function assignCoach(Request $request, $orderId)
    {
        $userId = Auth::id();
        $coachId = $request->input('coach_id');
        return $this->service->assignCoach($userId, $orderId, $coachId);
    }

    /**
     * 获取代理商配置
     */
    public function getAgentConfig($agentId)
    {
        $agent = AgentInfo::where('id', $agentId)
            ->where('state', 'enable')
            ->firstOrFail();

        $config = AgentConfig::where('agent_id', $agentId)->firstOrFail();

        return [
            'min_distance' => $config->min_distance,
            'min_fee' => $config->min_fee,
            'per_km_fee' => $config->per_km_fee
        ];
    }

    /**
     * 获取技师配置
     */
    public function getCoachConfig($coachId)
    {
        $coach = CoachUser::where('id', $coachId)
            ->where('state', 'enable')
            ->where('auth_state', 'passed')
            ->firstOrFail();

        $config = CoachConfig::where('coach_id', $coachId)->firstOrFail();

        return [
            'delivery_fee_type' => $config->delivery_fee_type,
            'charge_delivery_fee' => $config->charge_delivery_fee
        ];
    }

    /**
     * 计算路费金额
     */
    public function calculateDeliveryFee($coachId, $agentId, $distance)
    {
        $coach = CoachUser::where('id', $coachId)
            ->where('state', 'enable')
            ->where('auth_state', 'passed')
            ->firstOrFail();

        $coachConfig = CoachConfig::where('coach_id', $coachId)->firstOrFail();

        if (!$coachConfig->charge_delivery_fee) {
            return 0;
        }

        $agentConfig = AgentConfig::where('agent_id', $agentId)->firstOrFail();

        $fee = 0;
        if ($distance <= $agentConfig->min_distance) {
            $fee = $agentConfig->min_fee;
        } else {
            $extraDistance = $distance - $agentConfig->min_distance;
            $fee = $agentConfig->min_fee + ($extraDistance * $agentConfig->per_km_fee);
        }

        return $coachConfig->delivery_fee_type == 'round_trip' ? $fee * 2 : $fee;
    }

    /**
     * 计算订单金额
     */
    public function calculateOrderAmount($userId, $addressId, $coachId, $projectId, $agentId, $useBalance)
    {
        // 参数校验
        $user = User::where('id', $userId)
            ->where('status', 1)
            ->firstOrFail();

        $address = UserAddress::where('id', $addressId)
            ->where('user_id', $userId)
            ->firstOrFail();

        $coach = CoachUser::where('id', $coachId)
            ->where('state', 'enable')
            ->where('auth_state', 'passed')
            ->firstOrFail();

        $project = Project::where('id', $projectId)
            ->where('state', 'enable')
            ->firstOrFail();

        // 计算金额
        $projectAmount = $project->price;
        $deliveryFee = $this->calculateDeliveryFee($coachId, $agentId, $address->distance);
        $tipAmount = request()->has('order_id') ? Order::find(request()->input('order_id'))->tip_amount : 0;
        
        $couponAmount = 0;
        if (request()->has('coupon_id')) {
            $coupon = Coupon::where('id', request()->input('coupon_id'))
                ->where('state', 'enable')
                ->firstOrFail();
            $couponAmount = $coupon->amount;
        }

        $totalAmount = $projectAmount + $deliveryFee + $tipAmount - $couponAmount;

        $balanceAmount = 0;
        $payAmount = $totalAmount;

        if ($useBalance) {
            $wallet = UserWallet::where('user_id', $userId)->first();
            if ($wallet && $wallet->balance >= $totalAmount) {
                $balanceAmount = $totalAmount;
                $payAmount = 0;
            } else if ($wallet) {
                $balanceAmount = $wallet->balance;
                $payAmount = $totalAmount - $balanceAmount;
            }
        }

        return [
            'total_amount' => $totalAmount,
            'balance_amount' => $balanceAmount,
            'pay_amount' => $payAmount,
            'coupon_amount' => $couponAmount,
            'tip_amount' => $tipAmount,
            'project_amount' => $projectAmount,
            'delivery_fee' => $deliveryFee
        ];
    }

    /**
     * 创建订单
     */
    public function createOrder($userId, $projectId, $addressId, $coachId, $useBalance, $orderId = null)
    {
        return DB::transaction(function() use ($userId, $projectId, $addressId, $coachId, $useBalance, $orderId) {
            // 参数校验
            $user = User::where('id', $userId)
                ->where('status', 1)
                ->firstOrFail();

            $address = UserAddress::where('id', $addressId)
                ->where('user_id', $userId)
                ->firstOrFail();

            if (!$orderId) {
                $coach = CoachUser::where('id', $coachId)
                    ->where('state', 'enable')
                    ->where('auth_state', 'passed')
                    ->firstOrFail();
            }

            $project = Project::where('id', $projectId)
                ->where('state', 'enable')
                ->firstOrFail();

            // 创建订单
            $orderType = $orderId ? 'add_time' : 'normal';
            $amounts = $this->calculateOrderAmount($userId, $addressId, $coachId, $projectId, $project->agent_id, $useBalance);

            $order = new Order();
            $order->user_id = $userId;
            $order->project_id = $projectId;
            $order->address_id = $addressId;
            $order->coach_id = $coachId;
            $order->order_type = $orderType == 'normal' ? 0 : 1;
            $order->status = 0;
            $order->total_amount = $amounts['total_amount'];
            $order->balance_amount = $amounts['balance_amount'];
            $order->pay_amount = $amounts['pay_amount'];
            $order->coupon_amount = $amounts['coupon_amount'];
            $order->tip_amount = $amounts['tip_amount'];
            $order->project_amount = $amounts['project_amount'];
            $order->delivery_fee = $orderType == 'add_time' ? 0 : $amounts['delivery_fee'];
            $order->payment_type = $useBalance && $amounts['pay_amount'] == 0 ? 0 : 1;
            $order->save();

            // 创建订单历史
            if ($orderType == 'add_time') {
                OrderHistory::create([
                    'order_id' => $order->id,
                    'type' => 'add_time',
                    'user_id' => $userId
                ]);
            } else {
                OrderHistory::create([
                    'order_id' => $order->id,
                    'type' => 'create',
                    'user_id' => $userId
                ]);
            }

            // 余额支付处理
            if ($order->payment_type == 0) {
                $order->status = 1;
                $order->save();

                OrderHistory::create([
                    'order_id' => $order->id,
                    'type' => 'pay',
                    'user_id' => $userId
                ]);

                CoachSchedule::create([
                    'coach_id' => $coachId,
                    'date' => date('Y-m-d'),
                    'status' => 'busy'
                ]);

                return $order->id;
            }

            // 微信支付处理
            // TODO: 调用支付接口

            return $order->id;
        });
    }

    /**
     * 加钟
     */
    public function addTime($userId, $orderId)
    {
        $order = Order::where('id', $orderId)
            ->where('user_id', $userId)
            ->firstOrFail();

        return $this->createOrder($userId, $order->project_id, $order->address_id, $order->coach_id, 0, $orderId);
    }

    /**
     * 指定技师
     */
    public function assignCoach($userId, $orderId, $coachId)
    {
        return DB::transaction(function() use ($userId, $orderId, $coachId) {
            // 参数校验
            $user = User::where('id', $userId)
                ->where('status', 1)
                ->firstOrFail();

            $order = Order::where('id', $orderId)
                ->where('user_id', $userId)
                ->whereIn('status', [0, 1, 6])
                ->firstOrFail();

            $coach = CoachUser::where('id', $coachId)
                ->where('state', 'enable')
                ->where('auth_state', 'passed')
                ->firstOrFail();

            $schedule = CoachSchedule::where('coach_id', $coachId)
                ->where('date', date('Y-m-d'))
                ->where('status', 'free')
                ->firstOrFail();

            // 修改订单
            $order->coach_id = $coachId;
            if ($order->status == 0) {
                $amounts = $this->calculateOrderAmount($userId, $order->address_id, $coachId, $order->project_id, $order->agent_id, $order->payment_type == 0);
                
                $order->total_amount = $amounts['total_amount'];
                $order->balance_amount = $amounts['balance_amount'];
                $order->pay_amount = $amounts['pay_amount'];
                $order->coupon_amount = $amounts['coupon_amount'];
                $order->tip_amount = $amounts['tip_amount'];
                $order->project_amount = $amounts['project_amount'];
                $order->delivery_fee = $amounts['delivery_fee'];

                if ($order->payment_type == 0) {
                    $order->status = 1;
                }
            }
            if ($order->status == 1) {
                $order->status = 2;
            }
            $order->save();

            // 创建订单历史
            OrderHistory::create([
                'order_id' => $order->id,
                'type' => 'assign_coach',
                'user_id' => $userId,
                'coach_id' => $coachId
            ]);

            OrderHistory::create([
                'order_id' => $order->id,
                'type' => 'accept',
                'user_id' => $userId,
                'coach_id' => $coachId,
                'remark' => '抢单成功'
            ]);

            // 更新抢单池
            GrabOrder::where('order_id', $orderId)
                ->update(['status' => 2, 'coach_id' => $coachId]);

            // 更新排班
            $schedule->status = 'busy';
            $schedule->save();

            return true;
        });
    }
}