<?php

namespace App\Services\Admin;

use App\Models\Cases;
use App\Models\ForumPost;
use App\Models\Hub;
use App\Models\User;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

// ══════════════════════════════════════════════════════════════════
//  InPractice — Admin\AdminDashboardService
//  Location: app/Services/Admin/AdminDashboardService.php
//
//  All logic for the admin dashboard.
//  Returns one clean array to the controller.
//
//  Sections:
//    memberStats   → totals, active, suspended, new this week/month
//    caseStats     → per-hub breakdown of published / draft / review
//    forumStats    → total active posts, total replies
//    recentMembers → last 10 registrations with hub badges
//
//  Performance:
//    - Stats cached for 2 minutes — admin panel doesn't need live data
//    - Recent members NOT cached — admin always sees the latest
//    - Eager loading on recentMembers — no N+1
// ══════════════════════════════════════════════════════════════════

class AdminDashboardService
{
    /**
     * Get all data needed to render the admin dashboard.
     */
    public function getData(): array
    {
        return [
            'memberStats'   => $this->getMemberStats(),
            'caseStats'     => $this->getCaseStats(),
            'forumStats'    => $this->getForumStats(),
            'recentMembers' => $this->getRecentMembers(),
        ];
    }

    // ── Member Stats ──────────────────────────────────────────

    private function getMemberStats(): array
    {
        return Cache::remember('admin.member_stats', 120, function () {
            $total     = User::where('role', 'member')->count();
            $active    = User::where('role', 'member')->where('is_active', true)->count();
            $suspended = $total - $active;

            $newThisWeek = User::where('role', 'member')
                ->where('created_at', '>=', now()->subDays(7))
                ->count();

            $newThisMonth = User::where('role', 'member')
                ->where('created_at', '>=', now()->subDays(30))
                ->count();

            // Growth: compare this week vs last week
            $lastWeek = User::where('role', 'member')
                ->whereBetween('created_at', [now()->subDays(14), now()->subDays(7)])
                ->count();

            $weekGrowth = $lastWeek > 0
                ? round((($newThisWeek - $lastWeek) / $lastWeek) * 100)
                : ($newThisWeek > 0 ? 100 : 0);

            return [
                'total'          => $total,
                'active'         => $active,
                'suspended'      => $suspended,
                'new_this_week'  => $newThisWeek,
                'new_this_month' => $newThisMonth,
                'week_growth'    => $weekGrowth,  // percentage vs last week
            ];
        });
    }

    // ── Case Stats ─────────────────────────────────────────────

    private function getCaseStats(): array
    {
        return Cache::remember('admin.case_stats', 120, function () {
            $hubs = Hub::active()->orderBy('id')->get();

            // One query for all case counts grouped by hub and status
            $caseCounts = Cases::selectRaw('hub_id, status, COUNT(*) as cnt')
                ->groupBy('hub_id', 'status')
                ->get()
                ->groupBy('hub_id');

            // One query for all hub member counts
            $memberCounts = DB::table('user_hubs')
                ->selectRaw('hub_id, COUNT(*) as cnt')
                ->groupBy('hub_id')
                ->pluck('cnt', 'hub_id');

            return $hubs->map(function ($hub) use ($caseCounts, $memberCounts) {
                $stats     = $caseCounts[$hub->id] ?? collect();
                $byStatus  = $stats->pluck('cnt', 'status');

                $published = (int) ($byStatus['published'] ?? 0);
                $draft     = (int) ($byStatus['draft']     ?? 0);
                $review    = (int) ($byStatus['review']    ?? 0);
                $archived  = (int) ($byStatus['archived']  ?? 0);

                return [
                    'hub_id'      => $hub->id,
                    'name_en'     => $hub->name_en,
                    'name_ar'     => $hub->name_ar,
                    'color'       => $hub->color,
                    'icon'        => $hub->icon,
                    'total'       => $published + $draft + $review + $archived,
                    'published'   => $published,
                    'draft'       => $draft,
                    'review'      => $review,
                    'archived'    => $archived,
                    'hub_members' => (int) ($memberCounts[$hub->id] ?? 0),
                ];
            })->toArray();
        });
    }

    // ── Forum Stats ────────────────────────────────────────────

    private function getForumStats(): array
    {
        return Cache::remember('admin.forum_stats', 120, function () {
            $totalPosts   = ForumPost::where('status', 'active')->count();
            $openThreads  = ForumPost::where('status', 'active')
                ->where('post_type', 'question')
                ->count();
            $knowledgePosts = ForumPost::where('status', 'active')
                ->where('post_type', 'knowledge_share')
                ->count();

            return [
                'total_posts'      => $totalPosts,
                'open_threads'     => $openThreads,
                'knowledge_posts'  => $knowledgePosts,
            ];
        });
    }

    // ── Recent Members ─────────────────────────────────────────

    private function getRecentMembers(): array
    {
        // NOT cached — admin always sees the latest registrations
        return User::where('role', 'member')
            ->with(['hubs:id,name_en,name_ar,color'])
            ->select([
                'id',
                'name',
                'nickname',
                'email',
                'profession',
                'experience_level',
                'is_active',
                'created_at',
            ])
            ->orderByDesc('created_at')
            ->take(10)
            ->get()
            ->map(fn ($u) => [
                'id'               => $u->id,
                'name'             => $u->name,
                'nickname'         => $u->nickname,
                'email'            => $u->email,
                'profession'       => $u->profession,
                'experience_level' => $u->experience_level,
                'is_active'        => $u->is_active,
                'created_at'       => $u->created_at->diffForHumans(),
                'created_at_full'  => $u->created_at->format('d M Y'),
                'hubs'             => $u->hubs->map(fn ($h) => [
                    'id'      => $h->id,
                    'name_en' => $h->name_en,
                    'name_ar' => $h->name_ar,
                    'color'   => $h->color,
                ])->toArray(),
            ])
            ->toArray();
    }
}
