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

use App\Dicts;
use App\Core\Service;
use App\Models\Card\Card;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use App\Domains\Card\Repositories\CardRepository;
use App\Domains\Virtual\Repositories\OrderCardPartitionRepository;

class CardService extends Service
{
    protected $orderCardPartitionRepository;
    protected $cardRepository;

    protected static $typeNames = ['基础套餐', '基础续费', '续费包', '加油包'];

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

    /**
     * 卡列表
     *
     * @param array $conditions
     * @return mixed
     */
    public function index(array $conditions = [])
    {
        $limit = $conditions['limit'] ?? 20;
        $conditions['type'] = 0;

        $cards = $this->orderCardPartitionRepository->withConditions($conditions)->applyConditions()->paginate($limit);

        return static::transformer($cards);
    }

    /**
     * 格式转化
     *
     * @param mixed $cards
     * @return mixed
     */
    public static function transformer($cards)
    {
        $cards->load([
            'card:sim,imsi,iccid,virtual_activated_at,cancelled_at',
        ]);

        if (!empty($cards)) {
            $simArray = $cards->pluck('sim')->implode(',');
            $timelines = DB::select("select  * from get_timelines('{{$simArray}}'::INT8[]);");
            $timelines = collect($timelines)->collect()->groupBy('sim')->toArray();
        }

        $carrierOperators = app(Dicts::class)->get('carrier_operator');
        $cardStatus = app(Dicts::class)->get('card_status');

        $cards->transform(function ($item) use ($carrierOperators, $cardStatus, $timelines) {
            $_timelines = $timelines[$item->sim] ?? [];

            try {
                foreach ($_timelines as &$timeline) {
                    $package = PackageService::load($timeline['package_id']);
                    $timeline['type_name'] = self::$typeNames[$timeline['type']];
                    $timeline['name'] = $package['name'];
                    $timeline['service_start_at'] = $timeline['service_start_at'] ? Carbon::parse($timeline['service_start_at'])->format('Y-m') : '';
                    $timeline['service_end_at'] = $timeline['service_end_at'] ? Carbon::parse($timeline['service_end_at'])->format('Y-m') : '';
                }
            } catch (\Exception $e) {
                throw $e;
            }

            $company = CompanyService::load($item->company_id);
            $package = PackageService::load($item->package_id);
            $service_start_at = empty($_timelines) ? '' : min(array_pluck($_timelines, 'service_start_at'));
            $service_end_at = empty($_timelines) ? '' : max(array_pluck($_timelines, 'service_end_at'));

            $data = [
                'id' => sprintf('No%011d', $item->id),
                'sim' => $item->sim,
                'imsi' => $item->card['imsi'],
                'iccid' => $item->card['iccid'],
                'carrier_operator' => $carrierOperators[$package['carrier_operator']],
                'company_name' => $company['name'],
                'package_name' => $package['name'],
                'virtual_activated_at' => (string)$item->card['virtual_activated_at'],
                'cancelled_at' => (string)$item->card['cancelled_at'],
                'created_at' => (string)$item->created_at,
                'updated_at' => (string)$item->updated_at,
                'service_start_at' => $service_start_at,
                'service_end_at' => $service_end_at,
                'timelines' => $_timelines,
            ];

            $status = static::getStatus($data);

            $data['status'] = $status;
            $data['status_name'] =  $cardStatus[$status];

            return collect($data);
        });

        return collect($cards->toArray());
    }

    /**
     * 卡状态
     *
     * @param Card $card
     * @return void
     */
    public static function getStatus($card)
    {
        if ($card['cancelled_at']) {
            return 4;
        }

        if ($card['service_end_at'] && $card['service_end_at'] < date('Y-m')) {
            return 3;
        }

        if ($card['service_start_at']) {
            return 2;
        }

        if (Carbon::parse($card['created_at'])->diffInMonths(Carbon::now()) <= 6) {
            return 1;
        }

        return 1;
    }
}
