<?php
namespace App\Domains\Real\Services;

use App\Dicts;
use App\Core\Service;
use Illuminate\Support\Facades\Log;
use App\Exceptions\NotAllowedException;
use App\Domains\Virtual\Services\CompanyService;
use App\Domains\Virtual\Services\PackageService;
use App\Domains\Real\Repositories\OrderRepository;
use App\Domains\Real\Repositories\OrderCardPartitionRepository;
use App\Domains\Virtual\Repositories\OrderRepository as VirtualOrderRepository;
use App\Domains\Virtual\Repositories\OrderCardPartitionRepository as VirtualOrderCardPartitionRepository;

class OrderService extends Service
{
    public $orderRepository;
    public $orderCardPartitionRepository;

    /**
     * 构造函数
     *
     * @return void
     */
    public function __construct(OrderRepository $orderRepository, OrderCardPartitionRepository $orderCardPartitionRepository)
    {
        $this->orderRepository = $orderRepository;
        $this->orderCardPartitionRepository = $orderCardPartitionRepository;
    }

    /**
     * 订单列表
     *
     * @return void
     */
    public function index(array $conditions = [])
    {
        $conditions['type'] = $conditions['type'] ?? 0;
        $limit = $conditions['limit'] ?? 10;

        $carrierOperators = app(Dicts::class)->get('carrier_operator');
        $businessTypes = app(Dicts::class)->get('business_type');

        $res = $this->orderRepository->withConditions($conditions)->applyConditions()->paginate($limit);

        if (!$res->isEmpty()) {
            $cards = $this->orderCardPartitionRepository->selectRaw('
                order_id,SUM(counts) as counts,
                SUM(CASE virtual_order_id WHEN 0 THEN 0 ELSE counts END) as shipments,
                SUM(CASE WHEN refunded_at IS NULL THEN 0 ELSE counts END) as refunds
            ')
                ->withConditions(['type' => $conditions['type'], 'order_id', $res->pluck('id')->toArray()])
                ->groupBy('order_id')->get()->keyBy('order_id')->toArray();
        }

        $res->map(function ($item) use ($carrierOperators, $businessTypes, $cards) {
            $item->business_type_name = $businessTypes[$item->business_type] ?? '';
            $item->pay_channel_name = CommonService::namePayChannel($item->pay_channel);
            $item->company_name = CommonService::company($item->company_id)['name'];
            $item->package = CommonService::package($item->package_id);
            $item->package_name = $item->package['name'];
            $item->carrier_operator = $item->package['carrier_operator'];
            $item->carrier_operator_name = $carrierOperators[$item->carrier_operator];
            $item->unit_price = sprintf('%.02f', $item->unit_price/100);
            $item->total_price = sprintf('%.02f', $item->total_price/100);
            $item->shipments = $cards[$item->id]['shipments'] ?? 0;
            $item->counts = $cards[$item->id]['counts'] ?? 0;
            $item->refunds = $cards[$item->id]['refunds'] ?? 0;
        });

        return $res->sortByDesc('order_at')->values();
    }

    /**
     * 获取卡列表
     *
     * @param int $orderId
     * @return void
     */
    public function cards(array $conditions = [])
    {
        begin_time_consuming();

        $counts = $this->orderCardPartitionRepository->withConditions($conditions)->sum('counts');

        if ($counts > 200000) {
            throw new NotAllowedException("当前请求数据量过大，请筛选过滤后查询");
        }

        $cards = $this->orderCardPartitionRepository->withVirtual($conditions)->currentModel()->get()->toArray();

        $tmpCards = array_groupBy($cards, 'virtual_order_id');

        $orderIds = array_unique(array_keys($tmpCards));

        $key = array_search(0, $orderIds);

        if ($key !== false) {
            unset($orderIds[$key]);
        }

        $virtualOrders = [];
        // 有订单的从订单中读取公司和套餐
        if (!empty($orderIds)) {
            $virtualOrders = app(VirtualOrderRepository::class)->withConditions(['id' => $orderIds])->get()->keyBy('id')->toArray();
        }

        $companyService = app(CompanyService::class);
        $packageService = app(PackageService::class);

        foreach ($cards as &$item) {
            $item['sim'] = (string)$item['sim'];
            $item['company_id'] = $item['company_id'] ?? 0;
            $item['package_id'] = $item['package_id'] ?? 0;

            if ($item['virtual_order_id']) {
                $virtual = $virtualOrders[$item['virtual_order_id']];
                $item['company_id'] = $virtual['company_id'];
                $item['package_id'] = $virtual['package_id'];
            }

            $item['company_name'] = !$item['company_id'] ? '' : $companyService->load($item['company_id'])['name'] ?? '';
            $item['package_name'] = !$item['package_id'] ? '' : $packageService->load($item['package_id'])['name'] ?? '';
            $item['package_sn'] = !$item['package_id'] ? '' : $packageService->load($item['package_id'])['sn'] ?? '';
        }

        return array_values(array_sort($cards, function ($value) {
            return $value['order_id'] . '-' . $value['sim'];
        }));
    }
}
