<?php

namespace App\Console\Commands;

use App\Helpers\Constants;
use App\Models\CrawlerListenHistory;
use App\Models\Crontjob;
use App\Models\Report\DailyReport;
use App\Models\Report\MonthlyReport;
use App\Models\Report\WeeklyReport;
use App\Models\View\DailyReportView;
use App\Models\View\MonthlyReportView;
use App\Models\View\WeeklyReportView;
use App\Repositories\TrackRepository;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class CalculateReportCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'calculate:report {type?}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Tính toán số liệu báo cáo ngày/tuần/tháng';

    protected $trackRepository;

    /**
     * Create a new command instance.
     *
     * CalculateReportCommand constructor.
     * @param TrackRepository $trackRepository
     */
    public function __construct(TrackRepository $trackRepository)
    {
        parent::__construct();
        ini_set('max_execution_time', -1);
        $this->trackRepository = $trackRepository;
    }

    public function handle()
    {
        $type = $this->argument('type');

        if (empty($type) || !in_array($type, ['daily', 'weekly', 'monthly'])) {
            $type = $this->choice('Chọn loại báo cáo ', ['daily', 'weekly', 'monthly']);
        }

        // Ghi log xem có gọi không
        Crontjob::create(['message' => 'CalculateReportCommand is called (' . $type . ')']);

        // Xử lý di chuyển
        echo "\n Bắt đầu xử lý tính toán BXH: " . $type;

        switch ($type) {
            case 'daily':
                // Lấy ngày tạo BXH ngày từ cấu hình, nếu xử lý BXH ngày hôm sau thì ngày của BXH là ngày hôm trước.
                if (Constants::IS_CREATE_DAILY_RANKING_SAME_DAY) {
                    $date_daily_ranking = date('Y-m-d');
                } else {
                    $date_daily_ranking = date('Y-m-d', time() - 86400);
                }

                // Check xem đã insert vào report_views_daily chưa
                $check = DailyReport::where('date', $date_daily_ranking)->count();

                if($check >= 100){
                    echo "\n - BXH Ngày đã được tạo trước đó.";
                } else {
                    echo "\n - Bắt đầu xử lý BXH Ngày...";
                    $daily_data = DailyReportView::select('*')->take(100)->get()->toArray();
                    if (count($daily_data) > 0) {
                        $daily_report = [];
                        foreach ($daily_data as $key => $daily) {
                            $daily_report[$key]['date'] = $date_daily_ranking;
                            $daily_report[$key]['track_id'] = $daily['track_id'];

                            $daily_report[$key]['views_zing'] = $daily['date_zing'];
                            $daily_report[$key]['views_nct'] =$daily['date_nct'];
                            $daily_report[$key]['views_keeng'] = $daily['date_keeng'];

                            $daily_report[$key]['point_zing'] = $daily['point_zing'];
                            $daily_report[$key]['point_nct'] = $daily['point_nct'];
                            $daily_report[$key]['point_keeng'] = $daily['point_keeng'];

                            $daily_report[$key]['total_point'] = $daily['total_point'];
                            $daily_report[$key]['ranking'] = $key + 1;

                            $daily_report[$key]['created_at'] = Carbon::now();
                            $daily_report[$key]['updated_at'] = Carbon::now();
                        }
                        if (count($daily_report) > 0) {
                            DB::table(Constants::TABLE_REPORT_VIEWS_DAILY)->insert($daily_report);
                        }
                    }
                    echo "\n - Xử lý xong BXH Ngày.";
                }

                // Lấy ngày ghi log từ cấu hình, nếu xử lý log ngày hôm sau thì ngày của log là ngày hôm trước.
                if (Constants::IS_SAVE_LISTEN_LOG_SAME_DAY) {
                    $date_log = date('Y-m-d');
                } else {
                    $date_log = date('Y-m-d', time() - 86400);
                }

                // Check xem đã insert vào crawler_listen_histories chưa
                $check_log = CrawlerListenHistory::where('date_log', $date_log)->count();

                if($check_log >= 100){
                    echo "\n - Log ngày đã được tạo trước đó.";
                } else {
                    echo "\n - Bắt đầu xử lý Log ngày...";
                    // Lưu log lượt nghe theo ngày
                    $daily_data_all = DailyReportView::select('*')->get()->toArray();
                    if (count($daily_data_all) > 0) {
                        $daily_report = [];
                        foreach ($daily_data_all as $key => $daily) {
                            $daily_report[$key]['date_log'] = $date_log;
                            $daily_report[$key]['track_id'] = $daily['track_id'];
                            // Lượt nghe cộng dồn đến ngày
                            $daily_report[$key]['alltime_zing'] = $daily['alltime_zing'];
                            $daily_report[$key]['alltime_nct'] = $daily['alltime_nct'];
                            $daily_report[$key]['alltime_nhacvn'] = 0;
                            $daily_report[$key]['alltime_keeng'] = $daily['alltime_keeng'];
                            // Lượt nghe so với ngày hôm qua
                            $daily_report[$key]['zing_count'] = $daily['date_zing'];
                            $daily_report[$key]['nct_count'] =$daily['date_nct'];
                            $daily_report[$key]['nhacvn_count'] = 0;
                            $daily_report[$key]['keeng_count'] = $daily['date_keeng'];

                            $daily_report[$key]['total_listen'] = $daily['total_listen'];

                            $daily_report[$key]['created_at'] = Carbon::now();
                            $daily_report[$key]['updated_at'] = Carbon::now();
                        }
                        if (count($daily_report) > 0) {
                            DB::table(Constants::TABLE_CRAWLER_LISTEN_HISTORIES)->insert($daily_report);
                        }
                    }
                    echo "\n - Kết thúc xử lý Log ngày.";
                }

                break;

            case 'weekly':
                // Check xem đã insert vào report_views_weekly chưa
                $check = WeeklyReport::where('week', date('W'))
                    ->where('month', date('m'))
                    ->where('year', date('Y'))
                    ->count();

                if($check >= 100){
                    echo "\n Báo cáo đã được tổng hợp trước đó.";
                    return false;
                }

                if (strtoupper(date('D')) == 'SUN') {
                    $weekly_data = WeeklyReportView::select('*')->take(100)->get()->toArray();
                    if (count($weekly_data) > 0) {
                        $weekly_report = [];
                        foreach ($weekly_data as $key => $weekly) {
                            $weekly_report[$key]['week'] = date('W');
                            $weekly_report[$key]['month'] = date('m');
                            $weekly_report[$key]['year'] = date('Y');
                            $weekly_report[$key]['track_id'] = $weekly['track_id'];

                            $weekly_report[$key]['views_zing'] = $weekly['week_zing'];
                            $weekly_report[$key]['views_nct'] =$weekly['week_nct'];
                            $weekly_report[$key]['views_keeng'] = $weekly['week_keeng'];

                            $weekly_report[$key]['point_zing'] = $weekly['point_zing'];
                            $weekly_report[$key]['point_nct'] = $weekly['point_nct'];
                            $weekly_report[$key]['point_keeng'] = $weekly['point_keeng'];

                            $weekly_report[$key]['total_point'] = $weekly['total_point'];
                            $weekly_report[$key]['order'] = $key + 1;

                            $weekly_report[$key]['created_at'] = Carbon::now();
                            $weekly_report[$key]['updated_at'] = Carbon::now();
                        }

                        if (count($weekly_report) > 0) {
                            DB::table(Constants::TABLE_REPORT_VIEWS_WEEKLY)->insert($weekly_report);
                        }

                        // Check xem đã insert chưa
                        $check_again = WeeklyReport::where('week', date('W'))
                            ->where('month', date('m'))
                            ->where('year', date('Y'))
                            ->count();

                        if ($check_again >= 100) {
                            echo "\n Đã lưu dữ liệu báo cáo và bắt đầu reset lượt nghe tuần.";
                            // Reset số lượt nghe tháng về 0 trong bảng crawler_listens
                            DB::table(Constants::TABLE_CRAWLER_LISTENS)->update([
                                'week_zing' => 0,
                                'week_nct' => 0,
                                'week_nhacvn' => 0,
                                'week_keeng' => 0
                            ]);
                            echo "\n Đã reset lượt nghe tuần.";
                        }
                    }
                } else {
                    echo "\n Ngày thực hiện báo cáo tuần phải là Chủ nhật.";
                    return false;
                }

                break;
            case 'monthly':
                // Check xem đã insert vào reports_views_monthly chưa
                $check = MonthlyReport::where('month', date('m'))
                    ->where('year', date('Y'))
                    ->count();

                if($check >= 100){
                    echo "\n Báo cáo đã được tổng hợp trước đó.";
                    return false;
                }

                // Chỉ thực hiện nếu là ngày 21 hàng tháng, phải thực hiện trước 21h
                if (date('d') == 21) {
                    $monthly_data = MonthlyReportView::select('*')->take(100)->get()->toArray();
                    if (count($monthly_data) > 0) {
                        $monthly_report = [];
                        foreach ($monthly_data as $key => $monthly) {
                            $monthly_report[$key]['month'] = date('m');
                            $monthly_report[$key]['year'] = date('Y');
                            $monthly_report[$key]['track_id'] = $monthly['track_id'];

                            $monthly_report[$key]['views_zing'] = $monthly['month_zing'];
                            $monthly_report[$key]['views_nct'] = $monthly['month_nct'];
                            $monthly_report[$key]['views_keeng'] = $monthly['month_keeng'];

                            $monthly_report[$key]['point_zing'] = $monthly['point_zing'];
                            $monthly_report[$key]['point_nct'] = $monthly['point_nct'];
                            $monthly_report[$key]['point_keeng'] = $monthly['point_keeng'];

                            $monthly_report[$key]['total_point'] = $monthly['total_point'];
                            $monthly_report[$key]['order'] = $key + 1;

                            $monthly_report[$key]['created_at'] = Carbon::now();
                            $monthly_report[$key]['updated_at'] = Carbon::now();
                        }
                        if (count($monthly_report) > 0) {
                            DB::table(Constants::TABLE_REPORTS_VIEWS_MONTHLY)->insert($monthly_report);
                        }
                        // Check xem đã insert chưa
                        $check_again = MonthlyReport::where('month', date('m'))
                            ->where('year', date('Y'))
                            ->count();
                        if ($check_again >= 100) {
                            echo "\n Đã lưu dữ liệu báo cáo và bắt đầu reset lượt nghe tháng.";
                            // Reset số lượt nghe tháng về 0 trong bảng crawler_listens
                            DB::table(Constants::TABLE_CRAWLER_LISTENS)->update([
                                'month_zing' => 0,
                                'month_nct' => 0,
                                'month_nhacvn' => 0,
                                'month_keeng' => 0
                            ]);
                            echo "\n Đã reset lượt nghe tháng.";
                        }
                    }
                } else {
                    echo "\n Ngày thực hiện báo cáo tháng phải là ngày 21.";
                    return false;
                }
                break;
        }

        echo "\n Kết thúc xử lý tính toán BXH: " . $type . "\n";
    }
}