<?php

namespace App\Services\Application\Dashboard;

use App\Services\Core\BaseService;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

class DashboardService extends BaseService
{

    public function completionOverview($completions)
    {
        $week_container = array_fill(0, 7, 0);
        $total_token_week_map = $week_container;
        $completion_token_week_map = $week_container;
        $prompt_token_week_map = $week_container;

        // Month of Year Section
        $year_container = array_fill(0, 12, 0);
        $total_token_year_map = $year_container;
        $completion_token_year_map = $year_container;
        $prompt_token_year_map = $year_container;

        $check_last_or_this_month = request()->has('last_month')
            ? now()->subMonth()->daysInMonth
            : now()->daysInMonth;
        $month_container = array_fill(1, $check_last_or_this_month, 0);
        $total_token_month_map = $month_container;
        $completion_token_month_map = $month_container;
        $prompt_token_month_map = $month_container;

        $total_tokens = $completions->sum('total_tokens');

        $completion_tokens = $completions->sum('completion_tokens');

        $prompt_tokens = $completions->sum('prompt_tokens');

        $total_overview = $completions->get()->groupBy(function ($completion) {
            return date('Y-m-d', strtotime($completion->created_at));
        });

        list($total_token_week_map, $total_token_month_map, $total_token_year_map)
            = $this->completionFilters($total_overview, 'total_tokens', $total_token_week_map, $total_token_month_map, $total_token_year_map);

        list($completion_token_week_map, $completion_token_month_map, $completion_token_year_map)
            = $this->completionFilters($total_overview, 'completion_tokens', $completion_token_week_map, $completion_token_month_map, $completion_token_year_map);

        list($prompt_token_week_map, $prompt_token_month_map, $prompt_token_year_map)
            = $this->completionFilters($total_overview, 'prompt_tokens', $prompt_token_week_map, $prompt_token_month_map, $prompt_token_year_map);

        $completion_overview = [];

        if (\request()->has('last_seven_days') || \request()->has('this_week') || \request()->has('last_week')) {
            array_push(
                $completion_overview,
                $total_token_week_map,
                $completion_token_week_map,
                $prompt_token_week_map
            );
        } elseif (\request()->has('this_month') || \request()->has('last_month')) {
            array_push(
                $completion_overview,
                collect($total_token_month_map)->values(),
                collect($completion_token_month_map)->values(),
                collect($prompt_token_month_map)->values()
            );
        } elseif (\request()->has('this_year') || \request()->has('total')) {
            array_push(
                $completion_overview,
                $total_token_year_map,
                $completion_token_year_map,
                $prompt_token_year_map
            );
        }

        return [
            'completion_overview' => $completion_overview,
            'total_tokens' => $total_tokens,
            'completion_tokens' => $completion_tokens,
            'prompt_tokens' => $prompt_tokens,
        ];
    }

    public function completionCountOverview($completions)
    {

        $week_container = array_fill(0, 7, 0);
        $total_completion_week_map = $week_container;

        // Month of Year Section
        $year_container = array_fill(0, 12, 0);
        $total_completion_year_map = $year_container;

        $check_last_or_this_month = request()->has('last_month')
        ? now()->subMonth()->daysInMonth
            : now()->daysInMonth;
        $month_container = array_fill(1, $check_last_or_this_month, 0);
        $total_completion_month_map = $month_container;

        $total_completions = $completions->count();

        $total_overview = $completions->selectRaw('DATE(created_at) as created_date, COUNT(*) as count')
        ->groupBy('created_date')->get();

        list($total_completion_week_map, $total_completion_month_map, $total_completion_year_map)
            = $this->countFilters($total_overview, $total_completion_week_map, $total_completion_month_map, $total_completion_year_map);

        $completion_overview = [];

        if (\request()->has('last_seven_days') || \request()->has('this_week') || \request()->has('last_week')) {
            array_push(
                $completion_overview,
                $total_completion_week_map
            );
        } elseif (\request()->has('this_month') || \request()->has('last_month')) {
            array_push(
                $completion_overview,
                collect($total_completion_month_map)->values(),
            );
        } elseif (\request()->has('this_year') || \request()->has('total')) {
            array_push(
                $completion_overview,
                $total_completion_year_map
            );
        }

        return [
            'completion_overview' => $completion_overview,
            'total_completions' => $total_completions,
        ];
    }

    public function documentOverview($documents)
    {

        $week_container = array_fill(0, 7, 0);
        $total_document_week_map = $week_container;

        // Month of Year Section
        $year_container = array_fill(0, 12, 0);
        $total_document_year_map = $year_container;

        $check_last_or_this_month = request()->has('last_month')
            ? now()->subMonth()->daysInMonth
            : now()->daysInMonth;
        $month_container = array_fill(1, $check_last_or_this_month, 0);
        $total_document_month_map = $month_container;

        $total_documents = $documents->count();

        $total_overview = $documents->selectRaw('DATE(created_at) as created_date, COUNT(*) as count')
            ->groupBy('created_date')->get();

        list($total_document_week_map, $total_document_month_map, $total_document_year_map)
            = $this->countFilters($total_overview, $total_document_week_map, $total_document_month_map, $total_document_year_map);

        $document_overview = [];

        if (\request()->has('last_seven_days') || \request()->has('this_week') || \request()->has('last_week')) {
            array_push(
                $document_overview,
                $total_document_week_map
            );
        } elseif (\request()->has('this_month') || \request()->has('last_month')) {
            array_push(
                $document_overview,
                collect($total_document_month_map)->values(),
            );
        } elseif (\request()->has('this_year') || \request()->has('total')) {
            array_push(
                $document_overview,
                $total_document_year_map
            );
        }

        return [
            'document_overview' => $document_overview,
            'total_documents' => $total_documents,
        ];
    }


    public function statusFilters($filters, $WeekMap, $month, $YearMap)
    {
        foreach ($filters as $value) {
            if (\request()->has('last_seven_days') || \request()->has('this_week') || \request()->has('last_week')) {
                ++$WeekMap[Carbon::parse($value)->dayOfWeek];
            } elseif (\request()->has('this_month') || \request()->has('last_month')) {
                ++$month[Carbon::parse($value)->day];
            } elseif (\request()->has('this_year') || \request()->has('total')) {
                ++$YearMap[Carbon::parse($value)->month - 1];
            }
        }
        return [$WeekMap, $month, $YearMap];
    }

    public function completionFilters($filters, $column, $WeekMap, $month, $YearMap)
    {
        foreach ($filters as $key => $value) {
            $sum = 0;
            foreach ($value as $v) {
                $sum += $v->$column;
            }
            if (\request()->has('last_seven_days') || \request()->has('this_week') || \request()->has('last_week')) {
                $WeekMap[Carbon::parse($key)->dayOfWeek] += $sum;
            } elseif (\request()->has('this_month') || \request()->has('last_month')) {
                $month[Carbon::parse($key)->day] += $sum;
            } elseif (\request()->has('this_year') || \request()->has('total')) {
                $YearMap[Carbon::parse($key)->month - 1] += $sum;
            }
        }
        return [$WeekMap, $month, $YearMap];
    }

    public function countFilters($filters, $WeekMap, $month, $YearMap)
    {
        foreach ($filters as $item) {
            if (\request()->has('last_seven_days') || \request()->has('this_week') || \request()->has('last_week')) {
                $WeekMap[Carbon::parse($item->created_date)->dayOfWeek] += $item->count;
            } elseif (\request()->has('this_month') || \request()->has('last_month')) {
                $month[Carbon::parse($item->created_date)->day] += $item->count;
            } elseif (\request()->has('this_year') || \request()->has('total')) {
                $YearMap[Carbon::parse($item->created_date)->month - 1] += $item->count;
            }
        }
        return [$WeekMap, $month, $YearMap];
    }
}
