<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use App\Models\Artwork;
use App\Models\Artist;
use App\Models\Episode;


class PageController extends Controller
{
    public function landing(Request $request)
    {
        $user = auth()->user();
        $headerCounters = $this->getHeaderCounters();
        $recentEpisodes = $this->mostRecentEpisodes();
        $recentSubmissions = $this->mostRecentSubmissions();
        $leaderboard = $this->leaderboardTwelveMonthsLanding();
        return view('home.page', [
            'user' => $user,
            'pageTitle' => 'Home',
            'headerCounters' => $headerCounters,
            'recentEpisodes' => $recentEpisodes,
            'recentSubmissions' => $recentSubmissions,
            'leaderboard' => $leaderboard,
            'preferredTheme' => $request->session()->get('preferred_theme') ?? 'dark',
        ]);
    }

    public function leaderboards(Request $request)
    {
        $user = auth()->user();
        $current_year = now()->format('Y');
        $start_year = 2011;
        $years = [];
        while($start_year < $current_year) {
            $years[] = $start_year;
            $start_year++;
        }
        arsort($years);
        return view('leaderboards.leaderboards', [
            'user' => $user,
            'leaderboardAllTime' => $this->leaderboardAllTime(),
            'leaderboardPastTwelveMonths' => $this->leaderboardTwelveMonths(),
            'leaderboardRollingSixMonths' => $this->leaderboardRollingSixMonths(),
            'leaderboardRollingNinetyDays' => $this->leaderboardRollingNinetyDays(),
            'leaderboardYears' => $years,
        ]);
    }

    public function support(Request $request)
    {
        return view('home.support.page', [
            'user' => auth()->user(),
            'pageTitle' => 'History and Support',
            'headerCounters' => $this->getHeaderCounters(),
            'recentEpisodes' => $this->mostRecentEpisodes(),
            'recentSubmissions' => $this->mostRecentSubmissions(),
            'leaderboard' => $this->leaderboardTwelveMonthsLanding(),
            'preferredTheme' => $request->session()->get('preferred_theme') ?? 'dark',
        ]);
    }

    private function mostRecentSubmissions() {
        $artworks = Cache::remember('latestSubmissions', 30, function() {
            return Artwork::whereNotNull('approved_by')
                ->with('artist')
                ->with('episode')
                ->with('podcast')
                ->orderBy('created_at', 'desc')
                ->limit(10)
                ->get();
        });
        return $artworks;
    }

    private function mostRecentEpisodes()
    {
        $episodes = Cache::remember('latestEpisodes', 30, function() {
            return Episode::where('published', true)
                ->whereHas('artwork')
                ->with('podcast')
                ->with('artwork')
                ->with('artwork.artist')
                ->orderBy('episode_number', 'desc')
                ->limit(5)
                ->get();
        });
        return $episodes;
    }

    private function getHeaderCounters()
    {
        $headerCounters = [];
        $artworkCountNumber = Cache::remember('artworkCountNumber', 30, function() {
            return Artwork::whereNotNull('approved_by')->count();
        });
        $artistCountNumber = Cache::remember('artistCountNumber', 30, function() {
            return Artist::all()->count();
        });
        $episodeCountNumber = Cache::remember('episodeCountNumber', 30, function() {
            return Episode::all()->count();
        });
        $headerCounters['Artworks'] = $this->shortNumberCount($artworkCountNumber);
        $headerCounters['Artists'] = $this->shortNumberCount($artistCountNumber);
        $headerCounters['Episodes'] = $this->shortNumberCount($episodeCountNumber);
        return $headerCounters;
    }
    private function shortNumberCount($number)
    {
        $units = ['', 'K', 'M', 'B', 'T'];
        for ($i = 0; $number >= 1000; $i++) {
            $number /= 1000;
        }
        return [
            'number' => $this->numberFormatPrecision($number, 1), //number_format(floatval($number), 1),
            'unit' => $units[$i],
        ];
    }

    private function numberFormatPrecision($number, $precision = 2, $separator = '.')
    {
        $numberParts = explode($separator, $number);
        $response = $numberParts[0];
        if (count($numberParts)>1 && $precision > 0) {
            $response .= $separator;
            $response .= substr($numberParts[1], 0, $precision);
        }
        return $response;
    }

    private function leaderboardByYear($year) {
        $leaderboard = cache()->remember('leaderboardForYear' . $year, 30, function() {
            $startDate = Carbon::createFromFormat('Y-m-d', $year . '-01-01')->startOfDay()->format('Y-m-d');
            $endDate = $startDate->copy()->endOfYear()->format('Y-m-d');
            $leaderboard = DB::table('episodes')
            ->join('artworks', 'artworks.id', '=', 'episodes.artwork_id')
            ->join('artists', 'artists.id', '=', 'artworks.artist_id')
            ->select([
                DB::raw('artists.id as artistId'),
                DB::raw('artists.name as artistName'),
                DB::raw('count(artworks.id) as artworkCount')
            ])
            ->where('episodes.published', 1)
            ->where('episodes.episode_date', '>=', $startDate)
            ->where('episodes.episode_date', '<=', $endDate)
            ->groupBy('artistId')
            ->orderByDesc('artworkCount')
            ->limit(50)
            ->get();
            $leaderboard = $this->addArtistModelToLeaderboard($leaderboard);
            return $leaderboard;
        });
        return $leaderboard;
    }

    private function leaderboardTwelveMonths() {
        $leaderboard = cache()->remember('leaderboardTwelveMonths', 30, function() {
            $endDate = now()->endOfDay()->subYear()->format('Y-m-d');
            $leaderboard = DB::table('episodes')
            ->join('artworks', 'artworks.id', '=', 'episodes.artwork_id')
            ->join('artists', 'artists.id', '=', 'artworks.artist_id')
            ->select([
                DB::raw('artists.id as artistId'),
                DB::raw('artists.name as artistName'),
                DB::raw('count(artworks.id) as artworkCount')
            ])
            ->where('episodes.published', 1)
            ->where('episodes.episode_date', '>=', $endDate)
            ->groupBy('artistId')
            ->orderByDesc('artworkCount')
            ->limit(50)
            ->get();
            $leaderboard = $this->addArtistModelToLeaderboard($leaderboard);
            return $leaderboard;
        });
        return $leaderboard;
    }

    private function leaderboardTwelveMonthsLanding() {
        $leaderboard = cache()->remember('leaderboardTwelveMonthsLanding', 30, function() {
            $endDate = now()->endOfDay()->subYear()->format('Y-m-d');
            $leaderboard = DB::table('episodes')
            ->join('artworks', 'artworks.id', '=', 'episodes.artwork_id')
            ->join('artists', 'artists.id', '=', 'artworks.artist_id')
            ->select([
                DB::raw('artists.id as artistId'),
                DB::raw('artists.name as artistName'),
                DB::raw('count(artworks.id) as artworkCount')
            ])
            ->where('episodes.published', 1)
            ->where('episodes.episode_date', '>=', $endDate)
            ->groupBy('artistId')
            ->orderByDesc('artworkCount')
            ->limit(10)
            ->get();
            $leaderboard = $this->addArtistModelToLeaderboard($leaderboard);
            return $leaderboard;
        });
        return $leaderboard;
    }

    private function leaderboardAllTime() {
        $leaderboard = cache()->remember('leaderboardAllTime', 30, function() {
            $leaderboard = DB::table('episodes')
            ->join('artworks', 'artworks.id', '=', 'episodes.artwork_id')
            ->join('artists', 'artists.id', '=', 'artworks.artist_id')
            ->select([
                DB::raw('artists.id as artistId'),
                DB::raw('artists.name as artistName'),
                DB::raw('count(artworks.id) as artworkCount')
            ])
            ->where('episodes.published', 1)
            ->groupBy('artistId')
            ->orderByDesc('artworkCount')
            ->limit(100)
            ->get();
            $leaderboard = $this->addArtistModelToLeaderboard($leaderboard);
            return $leaderboard;
        });
        return $leaderboard;
    }

    private function leaderboardRollingSixMonths() {
        $leaderboard = cache()->remember('leaderboardRollingSixMonth', 30, function() {
            $endDate = now()->endOfDay()->subMonths(6)->format('Y-m-d');
            $leaderboard = DB::table('episodes')
            ->join('artworks', 'artworks.id', '=', 'episodes.artwork_id')
            ->join('artists', 'artists.id', '=', 'artworks.artist_id')
            ->select([
                DB::raw('artists.id as artistId'),
                DB::raw('artists.name as artistName'),
                DB::raw('count(artworks.id) as artworkCount')
            ])
            ->where('episodes.published', 1)
            ->where('episodes.episode_date', '>=', $endDate)
            ->groupBy('artistId')
            ->orderByDesc('artworkCount')
            ->limit(50)
            ->get();
            $leaderboard = $this->addArtistModelToLeaderboard($leaderboard);
            return $leaderboard;
        });
        return $leaderboard;
    }

    private function leaderboardRollingNinetyDays() {
        $leaderboard = cache()->remember('leaderboardNinetyDays', 30, function() {
            $endDate = now()->endOfDay()->subDays(90)->format('Y-m-d');
            $leaderboard = DB::table('episodes')
            ->join('artworks', 'artworks.id', '=', 'episodes.artwork_id')
            ->join('artists', 'artists.id', '=', 'artworks.artist_id')
            ->select([
                DB::raw('artists.id as artistId'),
                DB::raw('artists.name as artistName'),
                DB::raw('count(artworks.id) as artworkCount')
            ])
            ->where('episodes.published', 1)
            ->where('episodes.episode_date', '>=', $endDate)
            ->groupBy('artistId')
            ->orderByDesc('artworkCount')
            ->limit(50)
            ->get();
            $leaderboard = $this->addArtistModelToLeaderboard($leaderboard);
            return $leaderboard;
        });
        return $leaderboard;
    }

    private function addArtistModelToLeaderboard($leaderboard) {
        $artistIds = [];
        foreach ($leaderboard as $lb) {
            $artistIds[] = $lb->artistId;
        }
        $artists = Artist::whereIn('id', $artistIds)->get();
        foreach ($leaderboard as $lb) {
            $lb->artist = $artists->where('id', $lb->artistId)->first();
        }
        $p = 0;
        foreach ($leaderboard as $lb) {
            $p++;
            $lb->position = $p;
        }
        return $leaderboard;
    }

    public function setSessionTheme(Request $request) {


    }

}
