<?php

namespace App\Domains\Real\Commands\Sync;

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

class ActivatedSync extends Command
{
    protected $name = 'real:sync-activated';

    protected $description = '同步激活数据(每天同步昨天的激活数据)';

    protected $limit = 1000;

    public function handle()
    {
        $day = $this->getDay();
        $startMicrotime = new UTCDateTime($day->copy()->startOfDay());
        $endMicrotime = new UTCDateTime($day->copy()->endOfDay());

        if ($this->option('month')) {
            $startMicrotime = new UTCDateTime($day->copy()->subMonth()->startOfMonth());
        }

        $query = TblCard::where('pNo', 'No00000000768')->where('isDel', 0)
            ->where('saDate', 'exists', true)
            ->where('bNo', 'exists', true)
            ->where('saDate', '>=', $startMicrotime)
            ->where('saDate', '<=', $endMicrotime);

        $total = $query->count();

        $this->line('待同步条数:'.$total);

        $page = 1;

        while ($total) {
            if (($page - 1) * $this->limit >= $total) {
                break;
            }

            $res = $query->select(['cNo', 'saDate'])
                ->forPage($page, $this->limit)->get();

            $array = $res->map(function ($item) {
                return [
                    'sim' => $item['cNo'],
                    'activated_at' => $item['saDate'] ?  (string)Carbon::createFromTimestampMs(strval($item['saDate'])) : null,
                ];
            })->all();

            $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}");
            $simArray = implode(',', array_pluck($array, 'sim'));

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

            $page++;
        }

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

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

            return Carbon::parse($day)->startOfDay();
        }

        return Carbon::yesterday()->startOfDay();
    }

    protected function getOptions()
    {
        return [
            ['--month', null, InputOption::VALUE_NONE, '首次同步按月同步'],
        ];
    }

    protected function getArguments()
    {
        return [
            ['day', InputArgument::OPTIONAL, '要同步的数据日期，默认昨天  #示例: 2018-10-01'],
        ];
    }
}
