<?php

namespace App\Services\Member;

use App\Models\Cases;
use App\Models\CaseProgress;
use App\Models\Hub;
use App\Models\Sector;
use App\Models\User;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Cache;

// ══════════════════════════════════════════════════════════════════
//  InPractice — Member\CaseService
//  Location: app/Services/Member/CaseService.php
//
//  All member-facing case logic lives here.
//
//  Methods:
//    index()    → filtered, paginated case library with user progress
//    show()     → single case with full content + user progress
//    reveal()   → mark solution_revealed = true in case_progress
//    complete() → mark case as completed in case_progress
// ══════════════════════════════════════════════════════════════════

class CaseService
{
    /**
     * Filtered, paginated case library.
     * 12 cases per page — Project Bible.
     * Filters: hub_id, topic_slug, difficulty, layer, sector_id
     */
    public function index(User $user, array $filters = []): array
    {
        // ── Active hub — default to user's primary hub ─────────
        $activeHubId = (int) ($filters['hub_id'] ?? $user->hubs()->wherePivot('is_primary', true)->first()?->id
            ?? $user->hubs()->first()?->id);

        // ── Build query ────────────────────────────────────────
        $query = Cases::published()
            ->where('hub_id', $activeHubId)
            ->with(['sectors:id,name_en,name_ar'])
            ->select([
                'id', 'hub_id', 'topic_slug', 'topic_name_en', 'topic_name_ar',
                'title_en', 'title_ar', 'subtitle_en', 'subtitle_ar',
                'difficulty', 'layer', 'read_time_minutes',
                'sort_order', 'published_at',
            ])
            ->orderBy('sort_order')
            ->orderByDesc('published_at');

        if (!empty($filters['topic_slug'])) {
            $query->where('topic_slug', $filters['topic_slug']);
        }

        if (!empty($filters['difficulty'])) {
            $query->where('difficulty', $filters['difficulty']);
        }

        if (!empty($filters['layer'])) {
            $query->where('layer', $filters['layer']);
        }

        if (!empty($filters['sector_id'])) {
            $query->whereHas('sectors', function ($q) use ($filters) {
                $q->where('sectors.id', $filters['sector_id']);
            });
        }

        $cases = $query->paginate(12)->withQueryString();

        // ── Attach user progress to each case ──────────────────
        // One query — get all progress records for the cases on this page
        $caseIds    = $cases->pluck('id')->toArray();
        $progressMap = CaseProgress::where('user_id', $user->id)
            ->whereIn('case_id', $caseIds)
            ->get()
            ->keyBy('case_id');

        $cases->getCollection()->transform(function ($case) use ($progressMap) {
            $progress = $progressMap->get($case->id);
            $case->user_status           = $progress?->status ?? 'not_started';
            $case->solution_revealed     = (bool) ($progress?->solution_revealed ?? false);
            return $case;
        });

        // ── Filter options for the sidebar ────────────────────
        // Topics available in this hub (distinct)
        $topics = Cases::published()
            ->where('hub_id', $activeHubId)
            ->select('topic_slug', 'topic_name_en', 'topic_name_ar')
            ->distinct()
            ->orderBy('topic_name_en')
            ->get();

        return [
            'cases'       => $cases,
            'allHubs'     => $this->getHubs(),
            'userHubIds'  => $user->hubs()->pluck('hubs.id')->toArray(),
            'activeHubId' => $activeHubId,
            'topics'      => $topics,
            'sectors'     => $this->getSectors(),
            'filters'     => $filters,
            'totalCount'  => Cases::published()->where('hub_id', $activeHubId)->count(),
        ];
    }

    /**
     * Single case — full content for the reading experience.
     * Loads or creates a progress record for this user+case.
     */
    public function show(User $user, Cases $case): array
    {
        // Eager load sectors
        $case->load('sectors:id,name_en,name_ar');

        // Get or create progress record (marks as 'started')
        $progress = CaseProgress::firstOrCreate(
            ['user_id' => $user->id, 'case_id' => $case->id],
            ['status' => 'started', 'solution_revealed' => false]
        );

        return [
            'case'     => $this->formatCase($case),
            'progress' => [
                'status'            => $progress->status,
                'solution_revealed' => (bool) $progress->solution_revealed,
                'completed_at'      => $progress->completed_at?->toDateTimeString(),
                'case_rating'       => $progress->case_rating,
            ],
        ];
    }

    /**
     * Reveal solution — idempotent.
     * Sets solution_revealed = true, marks as 'started' if not yet touched.
     */
    public function reveal(User $user, Cases $case): CaseProgress
    {
        $progress = CaseProgress::firstOrCreate(
            ['user_id' => $user->id, 'case_id' => $case->id],
            ['status' => 'started']
        );

        if (!$progress->solution_revealed) {
            $progress->update(['solution_revealed' => true]);
        }

        return $progress;
    }

    /**
     * Mark complete — idempotent.
     * Sets status = completed, records completed_at timestamp.
     */
    public function complete(User $user, Cases $case): CaseProgress
    {
        $progress = CaseProgress::firstOrCreate(
            ['user_id' => $user->id, 'case_id' => $case->id],
            ['status' => 'started']
        );

        if ($progress->status !== 'completed') {
            $progress->update([
                'status'       => 'completed',
                'completed_at' => now(),
            ]);
        }

        return $progress;
    }

    // ── Private helpers ───────────────────────────────────────

    /**
     * Format a case for the Vue Show page.
     * Returns all bilingual fields — Vue picks the right one based on locale.
     */
    private function formatCase(Cases $case): array
    {
        return [
            'id'                      => $case->id,
            'hub_id'                  => $case->hub_id,
            'topic_slug'              => $case->topic_slug,
            'topic_name_en'           => $case->topic_name_en,
            'topic_name_ar'           => $case->topic_name_ar,
            'layer'                   => $case->layer,
            'difficulty'              => $case->difficulty,
            'read_time_minutes'       => $case->read_time_minutes,
            // EN content
            'title_en'                => $case->title_en,
            'subtitle_en'             => $case->subtitle_en,
            'situation_en'            => $case->situation_en,
            'challenge_questions_en'  => $case->challenge_questions_en,
            'solution_en'             => $case->solution_en,
            'bigger_lesson_en'        => $case->bigger_lesson_en,
            'skills_taught_en'        => $case->skills_taught_en,
            // AR content
            'title_ar'                => $case->title_ar,
            'subtitle_ar'             => $case->subtitle_ar,
            'situation_ar'            => $case->situation_ar,
            'challenge_questions_ar'  => $case->challenge_questions_ar,
            'solution_ar'             => $case->solution_ar,
            'bigger_lesson_ar'        => $case->bigger_lesson_ar,
            'skills_taught_ar'        => $case->skills_taught_ar,
            // Case data (numbers/tables)
            'case_data'               => $case->case_data,
            // Sectors
            'sectors'                 => $case->sectors->map(fn($s) => [
                'id'      => $s->id,
                'name_en' => $s->name_en,
                'name_ar' => $s->name_ar,
            ]),
        ];
    }

    private function getHubs(): \Illuminate\Database\Eloquent\Collection
    {
        return Cache::remember('hubs.active', 3600, function () {
            return Hub::where('is_active', true)
                ->select('id', 'name_en', 'name_ar', 'color', 'icon')
                ->orderBy('sort_order')
                ->get();
        });
    }

    private function getSectors(): \Illuminate\Database\Eloquent\Collection
    {
        return Cache::remember('sectors.active', 3600, function () {
            return Sector::where('is_active', true)
                ->select('id', 'name_en', 'name_ar')
                ->orderBy('sort_order')
                ->get();
        });
    }

        /**
     * Progress page data — all published cases for a hub with user progress.
     * Used by Member/Cases/Progress.vue
     */
    public function progress(User $user, array $filters = []): array
    {
        $activeHubId = (int) ($filters['hub_id']
            ?? $user->hubs()->wherePivot('is_primary', true)->first()?->id
            ?? $user->hubs()->first()?->id
            ?? 1);
    
        // All published cases for this hub — no pagination
        $cases = Cases::published()
            ->where('hub_id', $activeHubId)
            ->with('sectors:id,name_en,name_ar')
            ->orderBy('topic_slug')
            ->orderBy('sort_order')
            ->select([
                'id', 'hub_id', 'topic_slug', 'topic_name_en', 'topic_name_ar',
                'title_en', 'title_ar', 'difficulty', 'layer', 'read_time_minutes',
            ])
            ->get();
    
        // Load all progress for this user + hub in one query
        $progressMap = CaseProgress::where('user_id', $user->id)
            ->whereIn('case_id', $cases->pluck('id'))
            ->pluck('status', 'case_id');
    
        // Attach progress status to each case
        $casesWithProgress = $cases->map(function ($case) use ($progressMap) {
            $status = $progressMap[$case->id] ?? 'not_started';
            return [
                'id'              => $case->id,
                'title_en'        => $case->title_en,
                'title_ar'        => $case->title_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,
                'progress_status' => $status,
            ];
        });
    
        // Stats
        $completed   = $casesWithProgress->where('progress_status', 'completed')->count();
        $inProgress  = $casesWithProgress->where('progress_status', 'started')->count();
        $notStarted  = $casesWithProgress->where('progress_status', 'not_started')->count();
        $total       = $cases->count();
    
        return [
            'allHubs'     => $this->getHubs(),
            'activeHubId' => $activeHubId,
            'cases'       => $casesWithProgress->values()->all(),
            'stats'       => [
                'completed'   => $completed,
                'in_progress' => $inProgress,
                'not_started' => $notStarted,
                'total'       => $total,
            ],
        ];
    }
 
}
