<?php

namespace App\Domains\Virtual\Commands\Schedule;

use Carbon\Carbon;
use App\Models\Card\Card;
use App\Models\Mongo\TblCard;
use MongoDB\BSON\UTCDateTime;
use Illuminate\Console\Command;
use App\Models\Virtual\OrderCard;
use Illuminate\Support\Facades\DB;
use App\Domains\Card\Repositories\CardRepository;
use Symfony\Component\Console\Input\InputArgument;
use App\Domains\Virtual\Repositories\OrderCardPartitionRepository;

class VdActivated extends Command
{
    protected $name = 'virtual:schedule-vd-activate';

    protected $description = '同步已在VD上未激活卡的激活数据';

    const INTERVAL_MONTH = 6;

    public function handle()
    {
        begin_time_consuming();

        $datetime = $this->getDateTime();

        $time = $datetime->copy()->subMonths(self::INTERVAL_MONTH);

        $this->line('开始同步已在VD上未激活卡的激活数据');

        $startMicrotime = new UTCDateTime($datetime->copy()->subMonth());

        $cards = OrderCard::select('sim')->where('created_at', '>=', $time)
            ->whereNull('service_start_at')
            ->orderBy('created_at', 'desc')->get()->pluck('sim')->toArray();

        $this->line('同步条数 #:' . count($cards));

        $this->line('chunk');

        foreach (array_chunk($cards, 1000) as $simArray) {
            $simArray = array_map('strval', $simArray);

            $res = TblCard::select(['cNo', 'saDate'])
                ->whereIn('cNo', $simArray)
                ->where('saDate', 'exists', true)
                ->where('saDate', '>=', $startMicrotime)
                ->get()->toArray();

            if(empty($res)){
                echo '.';
            }

            if (!empty($res)) {
                echo '*';
                $array = [];
                foreach ($res as $item) {
                    $array[] = [
                        'sim' => $item['cNo'],
                        'activated_at' =>  (string)Carbon::createFromTimestampMs(strval($item['saDate'])),
                    ];
                }

                $table = app(Card::class)->getTable();
                $as = 'as_table';
                $reference = 'sim';

                $updates = "activated_at={$as}.activated_at::timestamp,
                virtual_activated_at=COALESCE({$table}.activated_at, {$as}.activated_at::timestamp)::timestamp";

                $parameters = collect($array)->map(function ($item) {
                    return "({$item['sim']}, '{$item['activated_at']}')";
                })->implode(', ');

                $from = "FROM (VALUES $parameters) AS {$as}(sim, activated_at)";

                $where = "WHERE {$table}.{$reference} = {$as}.{$reference}::int8";

                $sql =  trim("UPDATE {$table} SET {$updates} {$from} {$where}");
                $fixSimArray = implode(',', array_pluck($array, 'sim'));

                DB::statement($sql);
                DB::statement("select fix_timelines('{{$fixSimArray}}'::INT8[]);");
            }
        }

        app(CardRepository::class)->forgetCached();
        app(OrderCardPartitionRepository::class)->forgetCached();

        $this->line('结束同步已在VD上未激活卡的激活数据');
    }

    protected function getDateTime()
    {
        if ($month = $this->argument('month')) {
            if (!preg_match('/\d{4}-\d{1,2}/', $month)) {
                throw new \App\Exceptions\InvalidArgumentException('请输入正确的年月 #示例: 2018-10');
            }

            return Carbon::parse($month)->startOfMonth();
        }

        return Carbon::now()->startOfMonth();
    }

    protected function getArguments()
    {
        return [
            ['month', InputArgument::OPTIONAL, '要同步的数据月份，默认上个月  #示例: 2018-10'],
        ];
    }
}
