<?php

namespace App\Services;

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

// ══════════════════════════════════════════════════════════════════
//  InPractice — DashboardService
//  Location: app/Services/DashboardService.php
//
//  Contains ALL business logic for the member dashboard.
//  The controller calls getData() and gets back one clean array.
//
//  What this service returns:
//    - allHubs        → all three hubs for the hub switcher
//    - userHubIds     → which hubs the user joined (for highlighting)
//    - primaryHubId   → their default active hub
//    - heroCase       → featured case for the active hub
//    - recentPosts    → 3 latest Ask Members 4 Opinion posts per hub
//    - stats          → case counts and member counts per hub
//    - progress       → how many cases this user has completed
//    - unreadCount    → notification bell badge number
//
//  Performance rules:
//    - Hub stats cached for 5 minutes — they don't need to be live
//    - All relationships eager-loaded — zero N+1 queries
//    - Empty states handled gracefully — null hero case is valid
// ══════════════════════════════════════════════════════════════════

class DashboardService
{
    /**
     * Get all data needed to render the member dashboard.
     *
     * @param  User  $user  The authenticated member
     * @return array        Everything the Dashboard Vue page needs
     */
    public function getData(User $user): array
    {
        // ── Step 1: Load all three hubs ────────────────────────
        // Always all three — any user can browse any hub
        $allHubs = Hub::active()
                      ->ordered()
                      ->get()
                      ->map(fn ($hub) => [
                          'id'       => $hub->id,
                          'slug'     => $hub->slug,
                          'name_en'  => $hub->name_en,
                          'name_ar'  => $hub->name_ar,
                          'icon'     => $hub->icon,
                          'color'    => $hub->color,
                      ]);

        // ── Step 2: Resolve user's hub memberships ─────────────
        $userHubs = $user->hubs()->get();
        $userHubIds = $userHubs->pluck('id')->toArray();

        // Primary hub — the one marked is_primary = true
        // If somehow none is marked, fall back to the first hub they joined
        $primaryHub = $userHubs->firstWhere('pivot.is_primary', true)
                  ?? $userHubs->first();

        $primaryHubId = $primaryHub?->id ?? $allHubs->first()['id'];

        // ── Step 3: Hero case — featured case per hub ──────────
        // One hero case per hub, cached 10 minutes
        // Returns null if no cases published yet (launch state)
        $heroCases = [];

        foreach ($allHubs as $hub) {
            $heroCases[$hub['id']] = Cache::remember(
                "hero_case_hub_{$hub['id']}",
                600,
                function () use ($hub) {
                    $case = Cases::published()
                                 ->forHub($hub['id'])
                                 ->with('sectors')
                                 ->latest('published_at')
                                 ->first();

                    if (! $case) {
                        return null;
                    }

                    return [
                        'id'                  => $case->id,
                        'title_en'            => $case->title_en,
                        'title_ar'            => $case->title_ar,
                        'subtitle_en'         => $case->subtitle_en,
                        'subtitle_ar'         => $case->subtitle_ar,
                        'topic_name_en'       => $case->topic_name_en,
                        'topic_name_ar'       => $case->topic_name_ar,
                        'difficulty'          => $case->difficulty,
                        'read_time_minutes'   => $case->read_time_minutes,
                        'layer'               => $case->layer,
                        'sectors'             => $case->sectors->map(fn ($s) => [
                            'name_en' => $s->name_en,
                            'name_ar' => $s->name_ar,
                        ]),
                    ];
                }
            );
        }

        // ── Step 4: Hub stats — cached 5 minutes ───────────────
        $hubStats = [];

        foreach ($allHubs as $hub) {
            $hubStats[$hub['id']] = Cache::remember(
                "hub_stats_{$hub['id']}",
                300,
                function () use ($hub) {
                    return [
                        'case_count'   => Cases::published()->forHub($hub['id'])->count(),
                        'member_count' => \App\Models\UserHub::where('hub_id', $hub['id'])->count(),
                        'post_count'   => ForumPost::active()->forHub($hub['id'])->count(),
                    ];
                }
            );
        }

        // ── Step 5: User progress per hub ──────────────────────
        // How many cases the user has completed in each hub
        // Not cached — personal data, must be live
        $progressData = [];

        foreach ($allHubs as $hub) {
            $totalPublished  = $hubStats[$hub['id']]['case_count'];

            $completed = $user->caseProgress()
                              ->where('status', 'completed')
                              ->whereHas('case', fn ($q) => $q->where('hub_id', $hub['id']))
                              ->count();

            $progressData[$hub['id']] = [
                'completed' => $completed,
                'total'     => $totalPublished,
                'percent'   => $totalPublished > 0
                               ? (int) round(($completed / $totalPublished) * 100)
                               : 0,
            ];
        }

        // ── Step 6: Recent Ask Members 4 Opinion posts ─────────
        // 3 latest active posts per hub
        // Eager-load user for the author_name helper — no N+1
        $recentPosts = [];

        foreach ($allHubs as $hub) {
            $posts = ForumPost::active()
                              ->forHub($hub['id'])
                              ->with('user')
                              ->latest()
                              ->take(3)
                              ->get()
                              ->map(fn ($post) => [
                                  'id'          => $post->id,
                                  'title'       => $post->title,
                                  'author_name' => $post->author_name, // uses model helper — nickname safe
                                  'reply_count' => $post->reply_count,
                                  'like_count'  => $post->like_count,
                                  'created_at'  => $post->created_at->diffForHumans(),
                              ]);

            $recentPosts[$hub['id']] = $posts;
        }

        // ── Step 7: Unread notification count ──────────────────
        $unreadCount = $user->notifications()
                            ->whereNull('read_at')
                            ->count();

        // ── Return everything the controller needs ──────────────
        return [
            'allHubs'       => $allHubs,
            'userHubIds'    => $userHubIds,
            'primaryHubId'  => $primaryHubId,
            'heroCases'     => $heroCases,
            'hubStats'      => $hubStats,
            'progressData'  => $progressData,
            'recentPosts'   => $recentPosts,
            'unread_count'   => $unreadCount,
        ];
    }
}
