<?php

namespace AleshaCMS\Http\Controllers\Admin;

use AleshaCMS\Http\Controllers\Controller;
use AleshaCMS\Models\ViewLog;
use AleshaCMS\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class StatsController extends Controller
{
    private array $periods = [
        'today'    => 'Today',
        '7days'    => 'Last 7 Days',
        '30days'   => 'Last 30 Days',
        'mtd'      => 'Month to date',
        '12months' => 'Last 12 months',
        'ytd'      => 'Year to date',
        '3years'   => 'Last 3 years',
    ];

    public function index(Request $request)
    {
        $period = $request->get('period', '7days');
        if (!array_key_exists($period, $this->periods)) {
            $period = '7days';
        }

        [$start, $end, $type] = $this->periodBounds($period);

        $chart = $this->buildChart($start, $end, $type);

        $totalViews    = $chart->sum('views');
        $totalVisitors = $chart->sum('visitors');

        // Previous period comparison
        $span     = (int) $start->diffInDays($end) ?: 1;
        $prevEnd  = $start->copy()->subDay()->endOfDay();
        $prevStart= $prevEnd->copy()->subDays($span - 1)->startOfDay();

        $prevViews    = ViewLog::whereBetween('date', [$prevStart->toDateString(), $prevEnd->toDateString()])->count();
        $prevVisitors = ViewLog::whereBetween('date', [$prevStart->toDateString(), $prevEnd->toDateString()])
                          ->distinct('ip_hash')->count('ip_hash');

        $viewsDelta    = $prevViews    > 0 ? round((($totalViews    - $prevViews)    / $prevViews)    * 100) : null;
        $visitorsDelta = $prevVisitors > 0 ? round((($totalVisitors - $prevVisitors) / $prevVisitors) * 100) : null;

        // Most viewed posts
        $mostViewed = ViewLog::whereBetween('date', [$start->toDateString(), $end->toDateString()])
            ->whereNotNull('post_id')
            ->select('post_id', DB::raw('COUNT(*) as views'))
            ->groupBy('post_id')
            ->orderByDesc('views')
            ->take(10)
            ->get()
            ->map(function ($r) {
                $post = Post::find($r->post_id);
                return $post ? ['title' => $post->title, 'views' => $r->views, 'url' => '/' . $post->content_type . '/' . $post->slug] : null;
            })
            ->filter()
            ->values();

        // Referrers
        $referrers = ViewLog::whereBetween('date', [$start->toDateString(), $end->toDateString()])
            ->whereNotNull('referrer')
            ->select('referrer', DB::raw('COUNT(*) as views'))
            ->groupBy('referrer')
            ->orderByDesc('views')
            ->take(10)
            ->get();

        $maxReferrerViews = $referrers->max('views') ?: 1;
        $periods          = $this->periods;
        $periodLabel      = $this->periods[$period];

        return view('admin.stats.index', compact(
            'chart', 'type', 'period', 'periods', 'periodLabel',
            'totalViews', 'totalVisitors',
            'viewsDelta', 'visitorsDelta',
            'mostViewed', 'referrers', 'maxReferrerViews',
            'start', 'end'
        ));
    }

    private function periodBounds(string $period): array
    {
        return match($period) {
            'today'    => [now()->startOfDay(),                       now()->endOfDay(),    'day'],
            '30days'   => [now()->subDays(29)->startOfDay(),          now()->endOfDay(),    'day'],
            'mtd'      => [now()->startOfMonth()->startOfDay(),       now()->endOfDay(),    'day'],
            '12months' => [now()->subMonths(11)->startOfMonth(),      now()->endOfDay(),    'month'],
            'ytd'      => [now()->startOfYear(),                      now()->endOfDay(),    'month'],
            '3years'   => [now()->subYears(2)->startOfYear(),         now()->endOfYear(),   'year'],
            default    => [now()->subDays(6)->startOfDay(),           now()->endOfDay(),    'day'],   // 7days
        };
    }

    private function buildChart($start, $end, string $type): \Illuminate\Support\Collection
    {
        if ($type === 'day') {
            $rows = ViewLog::whereBetween('date', [$start->toDateString(), $end->toDateString()])
                ->select('date', DB::raw('COUNT(*) as views'), DB::raw('COUNT(DISTINCT ip_hash) as visitors'))
                ->groupBy('date')->orderBy('date')->get()
                ->keyBy(fn($r) => $r->date->format('Y-m-d'));

            $chart   = collect();
            $current = $start->copy()->startOfDay();
            while ($current <= $end) {
                $key        = $current->format('Y-m-d');
                $row        = $rows[$key] ?? null;
                $chart[$key] = ['views' => $row?->views ?? 0, 'visitors' => $row?->visitors ?? 0];
                $current->addDay();
            }
            return $chart;
        }

        if ($type === 'month') {
            $rows = ViewLog::whereBetween('date', [$start->toDateString(), $end->toDateString()])
                ->select(DB::raw("DATE_FORMAT(date,'%Y-%m') as month_key"), DB::raw('COUNT(*) as views'), DB::raw('COUNT(DISTINCT ip_hash) as visitors'))
                ->groupBy('month_key')->orderBy('month_key')->get()
                ->keyBy('month_key');

            $chart   = collect();
            $current = $start->copy()->startOfMonth();
            while ($current <= $end) {
                $key        = $current->format('Y-m');
                $row        = $rows[$key] ?? null;
                $chart[$key] = ['views' => $row?->views ?? 0, 'visitors' => $row?->visitors ?? 0];
                $current->addMonth();
            }
            return $chart;
        }

        // year
        $rows = ViewLog::whereBetween('date', [$start->toDateString(), $end->toDateString()])
            ->select(DB::raw('YEAR(date) as year_key'), DB::raw('COUNT(*) as views'), DB::raw('COUNT(DISTINCT ip_hash) as visitors'))
            ->groupBy('year_key')->orderBy('year_key')->get()
            ->keyBy('year_key');

        $chart   = collect();
        $current = $start->copy()->startOfYear();
        while ($current <= $end) {
            $key        = $current->format('Y');
            $row        = $rows[$key] ?? null;
            $chart[$key] = ['views' => $row?->views ?? 0, 'visitors' => $row?->visitors ?? 0];
            $current->addYear();
        }
        return $chart;
    }
}
