<?php

namespace App\Helpers;

use App\Models\Episode;
use App\Models\Hentai;
use App\Models\PopularMonthly;
use App\Models\PopularWeekly;
use App\Models\PopularDaily;

use Conner\Tagging\Model\Tag;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;

class CacheHelper
{
    public static function getRecentlyReleased(bool $guest)
    {
        $guestString = $guest ? 'guest' : 'authed';
        return Cache::remember("recently_released_".$guestString, now()->addMinutes(60), function () use ($guest) {
            return Episode::with('gallery')
                ->when($guest, fn ($query) => $query->withoutTags(['loli', 'shota']))
                ->orderBy('release_date', 'desc')
                ->limit(16)
                ->get();
        });
    }

    public static function getRecentlyUploaded(bool $guest)
    {
        $guestString = $guest ? 'guest' : 'authed';
        return Cache::remember("recently_uploaded".$guestString, now()->addMinutes(5), function () use ($guest) {
            return Episode::with('gallery')
                ->when($guest, fn ($query) => $query->withoutTags(['loli', 'shota']))
                ->orderBy('created_at', 'desc')
                ->limit(16)
                ->get();
        });
    }

    public static function getTotalViewCount()
    {
        return Cache::remember("total_view_count", now()->addMinutes(60), function () {
            return Episode::sum('view_count');
        });
    }

    public static function getTotalEpisodeCount()
    {
        return Cache::remember("total_episode_count", now()->addMinutes(60), function () {
            return Episode::count();
        });
    }

    public static function getTotalHentaiCount()
    {
        return Cache::remember("total_hentai_count", now()->addMinutes(60), function () {
            return Hentai::count();
        });
    }

    public static function getTotalMonthlyViews()
    {
        return Cache::remember("total_monthly_view_count", now()->addMinutes(60), function () {
            return PopularMonthly::count();
        });
    }

    public static function getPopularAllTime(bool $guest)
    {
        $guestString = $guest ? 'guest' : 'authed';
        return Cache::remember("top_hentai_alltime".$guestString, now()->addMinutes(360), function () use ($guest) {
            return Episode::with('gallery')
                ->when($guest, fn ($query) => $query->withoutTags(['loli', 'shota']))
                ->orderBy('view_count','desc')
                ->limit(16)
                ->get();
        });
    }

    public static function getPopularMonthly()
    {
        return Cache::remember("top_hentai_monthly", now()->addMinutes(360), function () {
            return PopularMonthly::groupBy('episode_id')
                ->select('episode_id', DB::raw('count(*) as total'))
                ->with('episode.gallery')
                ->orderBy('total', 'desc')
                ->limit(16)
                ->get();
        });
    }

    public static function getPopularWeekly()
    {
        return Cache::remember("top_hentai_weekly", now()->addMinutes(360), function () {
            return PopularWeekly::groupBy('episode_id')
                ->select('episode_id', DB::raw('count(*) as total'))
                ->with('episode.gallery')
                ->with('episode.studio')
                ->orderBy('total', 'desc')
                ->limit(16)
                ->get();
        });
    }

    public static function getPopularDaily()
    {
        return Cache::remember("top_hentai_daily", now()->addMinutes(30), function () {
            return PopularDaily::groupBy('episode_id')
                ->select('episode_id', DB::raw('count(*) as total'))
                ->with('episode.gallery')
                ->orderBy('total', 'desc')
                ->limit(16)
                ->get();
        });
    }

    public static function getMostLikes()
    {
        return Cache::remember("top_likes", now()->addMinutes(30), function () {
            return DB::table('markable_likes')->groupBy('markable_id')->select('markable_id', DB::raw('count(*) as total'))->orderBy('total', 'desc')->limit(16)->get();
        });
    }

    public static function getAllTags()
    {
        return Cache::remember("all_tags", now()->addMinutes(10080), function () {
            return Tag::where('count', '>', 0)->orderBy('slug', 'ASC')->get();
        });
    }

    public static function getLatestComments()
    {
        return Cache::remember("latest_comments", now()->addMinutes(60), function () {
            return DB::table('comments')->latest()->take(10)->get();
        });
    }
}
