<?php

namespace App\Domains\Stats\Services;

use App\Dicts;
use App\Core\Service;
use Illuminate\Support\Facades\DB;
use App\Exceptions\NotAllowedException;
use App\Domains\Virtual\Services\CommonService;
use App\Domains\Virtual\Services\PackageService;
use App\Domains\Virtual\Repositories\OrderRepository;
use App\Domains\Virtual\Repositories\CompanyRepository;
use App\Domains\Virtual\Repositories\PackageRepository;
use App\Domains\Virtual\Repositories\OrderCardPartitionRepository;

class OrderService extends Service
{
    protected $companyRepository;
    protected $packageRepository;
    protected $orderRepository;
    protected $orderCardPartitionRepository;

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


    /**
     * 统计
     *
     * @return void
     */
    public function index(array $conditions = [])
    {
        $repository =  $this->orderCardPartitionRepository->where('type', $conditions['type']);

        $companies = $this->companyRepository->withTrashed()->get()->pluck('name', 'id')->toArray();
        $packages = $this->packageRepository->withTrashed()->get()->pluck('name', 'id')->toArray();

        $select = [
            DB::raw("array_to_string(array_agg(id), ',') as order_id"),
            'company_id',
            'package_id',
            'pay_channel',
            DB::raw('SUM(custom_price) as custom_price'),
        ];

        $orders = $this->orderRepository->select($select)->withConditions($conditions)->applyConditions()
            ->groupBy(['company_id', 'package_id', 'pay_channel'])->paginate($conditions['limit']);

        $order_ids = [];
        $groups = [];

        foreach ($orders as $i => $order) {
            $order->gid = $i;
            $o_ids = str_to_array($order->order_id);

            foreach ($o_ids as $v) {
                $groups[$v] = "($i, $v)";
            }

            $order_ids = array_merge($order_ids, $o_ids);
        }

        $order_ids = array_unique($order_ids);

        $values = implode(',', $groups);
        $join = DB::raw("(VALUES $values) as t(gid, o_id)");

        $members = collect();

        if (!empty($groups)) {
            $members = $repository->join($join, 'o_id', '=', 'order_id')->select([
                'gid',
                DB::raw('SUM(counts) as counts'),
                DB::raw('COUNT(distinct sim) as members'),
            ])->withConditions(['order_id' => $order_ids])->groupBy('gid')->get();
        }

        $orders->map(function ($item) use ($companies, $packages, $members) {
            $item->company_name = $companies[$item->company_id];
            $item->package_name = $packages[$item->package_id];

            $item->members = $members[$item->gid]['members'] ?? 0;
            $item->counts = $members[$item->gid]['counts'] ?? 0;

            $item->custom_price = sprintf('%.02f', $item->custom_price / 100);

            $item->pay_channel_name = CommonService::namePayChannel($item->pay_channel);

            // 为兼容旧系统的错误做的处理
            $this->oldDataCount($item);
        });

        return $orders->where('counts', '<>', 0)->values();
    }

    // 为兼容旧系统的错误做的处理
    private function oldDataCount(&$item)
    {
        $data = [
            3389 => ['members' => 1, 'counts' => 1, 'custom_price' => 60],   // 福建省福信富通网络科技股份有限公司微信支付Y02 2016
            3768 => ['members' => -8, 'counts' => -4, 'custom_price' => -120], // 深圳市美凯欣科技有限公司银行转账Y02 2016
            4454 => ['members' => -3, 'counts' => 0, 'custom_price' => 0], // 深圳市美凯欣科技有限公司银行转账Y02 2016
            5170 => ['members' => -10, 'counts' => -10, 'custom_price' => -500], // 深圳市美凯欣科技有限公司银行转账Y02 2016
            9181 => ['members' => 1, 'counts' => 1, 'custom_price' => 36],  // 福建省福信富通网络科技股份有限公司微信支付Y02 2017-06
            12049 => ['members' => 19, 'counts' => 19, 'custom_price' => 1140], // 福建省福信富通网络科技股份有限公司微信支付Y02 2017-08
            13329 => ['members' => 3, 'counts' => 3, 'custom_price' => 180], // 福建省福信富通网络科技股份有限公司微信支付Y02 2017-09
            14345 => ['members' => -18, 'counts' => -18, 'custom_price' => -1056], // 福建省福信富通网络科技股份有限公司微信支付Y02 2017-10
            15061 => ['members' => -6, 'counts' => -6, 'custom_price' => -360], // 福建省福信富通网络科技股份有限公司微信支付Y02 2017-11
            6519 => ['members' => -1, 'counts' => -1, 'custom_price' => -8], // 深圳市和佳艺物联网有限公司支付宝Y01 2017
            8069 => ['members' => -1, 'counts' => -1, 'custom_price' => -6], // 深圳市和佳艺物联网有限公司支付宝Y01 2017
            15889 => ['members' => 1, 'counts' => 1, 'custom_price' => 8], // 深圳市和佳艺物联网有限公司支付宝Y01
            6732 => ['members' => -1, 'counts' => -1, 'custom_price' => -8], // 深圳市路科科技有限公司支付宝Y01
            5944 => ['members' => -4, 'counts' => -4, 'custom_price' => -180], // 深圳市路科科技有限公司支付宝Y01
            5944 => ['members' => -4, 'counts' => -4, 'custom_price' => -180], // 深圳市路科科技有限公司支付宝Y01
            6456 => ['members' => -1, 'counts' => -1, 'custom_price' => -30], // 深圳市路科科技有限公司支付宝Y01
            7819 => ['members' => -1, 'counts' => -1, 'custom_price' => -8], // 深圳市美凯欣科技有限公司支付宝Y02
            6456 => ['members' => -1, 'counts' => -1, 'custom_price' => -30], // 深圳市美凯欣科技有限公司银行转账Y02
            8203 => ['members' => -3, 'counts' => -3, 'custom_price' => -54], // 深圳市美凯欣科技有限公司银行转账Y02
            9272 => ['members' => -21, 'counts' => -16, 'custom_price' => -820], // 深圳市美凯欣科技有限公司银行转账Y02
            11070 => ['members' => 3, 'counts' => 4, 'custom_price' => 120], // 深圳市美凯欣科技有限公司银行转账Y02
            12357 => ['members' => 14, 'counts' => 14, 'custom_price' => 785.5], // 深圳市美凯欣科技有限公司银行转账Y02
            13390 => ['members' => 11, 'counts' => 11, 'custom_price' => 530], // 深圳市美凯欣科技有限公司银行转账Y02
            14432 => ['members' => 3, 'counts' => 3, 'custom_price' => 150], // 深圳市美凯欣科技有限公司银行转账Y02
            16358 => ['members' => 3, 'counts' => 3, 'custom_price' => 64.5], // 深圳市美凯欣科技有限公司银行转账Y02
            7734 => ['members' => -1, 'counts' => -1, 'custom_price' => -50], // 深圳思畅智能系统有限公司银行转账Y02
            // 19585 => ['members' => 25, 'counts' => 25, 'custom_price' => 425], // 深圳市康凯斯信息技术有限公司Y-02 2017-11
        ];

        $o_ids = str_to_array($item->order_id);

        foreach ($o_ids as $id) {
            if (in_array($id, array_keys($data))) {
                $item->members = $item->members + $data[$id]['members'] ?? 0;
                $item->counts = $item->counts + $data[$id]['counts'] ?? 0;
                $item->custom_price = $item->custom_price + $data[$id]['custom_price'] ?? 0;
                $item->custom_price = sprintf('%.02f', $item->custom_price);
            }
        }
    }

    /**
     * 明细
     *
     * @return void
     */
    public function detail(array $conditions = [])
    {
        $repository =  $this->orderCardPartitionRepository->where('type', $conditions['type']);

        $cards = $repository->withConditions($conditions)->applyConditions()->paginate($conditions['limit']);

        $cards = self::detailTransformer($cards);

        if (in_array($conditions['type'], [2, 3])) {
            $basePackages = app(OrderCardPartitionRepository::class)->getCardBasePackages($cards->pluck('sim')->toArray())->keyBy('sim')->toArray();
            $cards->map(function ($item) use ($basePackages) {
                $item->base_package_name = PackageService::load($basePackages[$item['sim']]['package_id'])['name'];
            });
        }

        return $cards;
    }

    /**
     * 格式转化
     *
     * @param mixed $cards
     * @return mixed
     */
    public static function detailTransformer($cards)
    {
        $companies = app(CompanyRepository::class)->withTrashed()->get()->pluck('name', 'id')->toArray();
        $packages = app(PackageRepository::class)->withTrashed()->get()->keyBy('id')->toArray();
        $orders = app(OrderRepository::class)->withTrashed()
            ->select(['id', 'unit_price', 'pay_channel', 'order_at'])
            ->withConditions(['id' => array_unique(array_pluck($cards, 'order_id'))])->get()->keyBy('id')->toArray();
        $carrierOperators = app(Dicts::class)->get('carrier_operator');

        $cards->map(function ($item) use ($companies, $packages, $carrierOperators, $orders) {
            $package = $packages[$item->package_id];
            $order = $orders[$item->order_id];
            $item->company_name = $companies[$item->company_id];
            $item->package_name = $package['name'];
            $item->carrier_operator_name = $carrierOperators[$package['carrier_operator']];
            $item->service_months = $package['service_months'];
            $item->unit_price = sprintf('%.02f', $order['unit_price'] / 100);
            $item->pay_channel_name = CommonService::namePayChannel($order['pay_channel']);
            $item->order_at = $order['order_at'];
        });

        return $cards;
    }
}
