<?php

namespace App\Services\Admin;

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

// ══════════════════════════════════════════════════════════════════
//  InPractice — Admin\CaseService
//  Location: app/Services/Admin/CaseService.php
//
//  All admin case management logic lives here.
//  Controller calls these methods — nothing else.
//
//  Methods:
//    index()    → paginated case list with optional filters
//    create()   → data needed to render the create form
//    store()    → create a new case + attach sectors
//    edit()     → load a case for editing
//    update()   → update case fields + sync sectors
//    publish()  → set status = published, record published_at
//    archive()  → set status = archived
//    destroy()  → hard delete the case
// ══════════════════════════════════════════════════════════════════

class CaseService
{
    /**
     * Paginated list for admin cases table.
     * Filters: hub_id, status, difficulty, search (title_en).
     */
    public function index(array $filters = []): array
    {
        $query = Cases::with(['hub', 'sectors'])
            ->select([
                'id', 'hub_id', 'topic_slug', 'topic_name_en',
                'title_en', 'title_ar', 'difficulty', 'layer',
                'status', 'sort_order', 'published_at', 'created_at',
            ])
            ->orderBy('sort_order')
            ->orderByDesc('created_at');

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

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

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

        if (!empty($filters['search'])) {
            $search = $filters['search'];
            $query->where(function ($q) use ($search) {
                $q->where('title_en', 'like', "%{$search}%")
                  ->orWhere('title_ar', 'like', "%{$search}%")
                  ->orWhere('topic_name_en', 'like', "%{$search}%");
            });
        }

        return [
            'cases'   => $query->paginate(20)->withQueryString(),
            'hubs'    => $this->getHubs(),
            'filters' => $filters,
        ];
    }

    /**
     * Data needed to render the create form.
     */
    public function create(): array
    {
        return [
            'hubs'    => $this->getHubs(),
            'sectors' => $this->getSectors(),
            'case'    => null,
        ];
    }

    /**
     * Create a new case and attach sectors.
     * Wrapped in a DB transaction — either everything saves or nothing does.
     */
    public function store(array $data, int $adminId): Cases
    {
        return DB::transaction(function () use ($data, $adminId) {
            $sectorIds = $data['sector_ids'] ?? [];
            unset($data['sector_ids']);

            $case = Cases::create([
                'hub_id'                  => $data['hub_id'],
                'created_by'              => $adminId,
                'topic_slug'              => $data['topic_slug'],
                'topic_name_en'           => $data['topic_name_en'],
                'topic_name_ar'           => $data['topic_name_ar'],
                'layer'                   => $data['layer'],
                'difficulty'              => $data['difficulty'],
                'title_en'                => $data['title_en'],
                'subtitle_en'             => $data['subtitle_en'] ?? null,
                'situation_en'            => $data['situation_en'],
                'challenge_questions_en'  => $data['challenge_questions_en'],
                'solution_en'             => $data['solution_en'],
                'bigger_lesson_en'        => $data['bigger_lesson_en'],
                'skills_taught_en'        => $data['skills_taught_en'],
                'title_ar'                => $data['title_ar'] ?? null,
                'subtitle_ar'             => $data['subtitle_ar'] ?? null,
                'situation_ar'            => $data['situation_ar'] ?? null,
                'challenge_questions_ar'  => $data['challenge_questions_ar'] ?? null,
                'solution_ar'             => $data['solution_ar'] ?? null,
                'bigger_lesson_ar'        => $data['bigger_lesson_ar'] ?? null,
                'skills_taught_ar'        => $data['skills_taught_ar'] ?? null,
                'case_data'               => $data['case_data'] ?? null,
                'read_time_minutes'       => $data['read_time_minutes'] ?? 10,
                'sort_order'              => $data['sort_order'] ?? 0,
                'status'                  => 'draft',
            ]);

            if (!empty($sectorIds)) {
                $case->sectors()->sync($sectorIds);
            }

            $this->clearHubCache($case->hub_id);

            return $case;
        });
    }

    /**
     * Load a case with its sector IDs for the edit form.
     */
    public function edit(Cases $case): array
    {
        $case->load(['hub', 'sectors']);

        return [
            'case'    => array_merge($case->toArray(), [
                'sector_ids' => $case->sectors->pluck('id')->toArray(),
            ]),
            'hubs'    => $this->getHubs(),
            'sectors' => $this->getSectors(),
        ];
    }

    /**
     * Update an existing case and sync sectors.
     */
    public function update(Cases $case, array $data): Cases
    {
        return DB::transaction(function () use ($case, $data) {
            $sectorIds = $data['sector_ids'] ?? null;
            unset($data['sector_ids']);

            $case->update($data);

            // Only sync if sector_ids was explicitly sent
            if ($sectorIds !== null) {
                $case->sectors()->sync($sectorIds);
            }

            $this->clearHubCache($case->hub_id);

            return $case->fresh(['hub', 'sectors']);
        });
    }

    /**
     * Publish a case — makes it visible to members.
     */
    public function publish(Cases $case): Cases
    {
        $case->update([
            'status'       => 'published',
            'published_at' => $case->published_at ?? now(),
        ]);

        $this->clearHubCache($case->hub_id);

        return $case;
    }

    /**
     * Archive a case — hides it from members without deleting.
     */
    public function archive(Cases $case): Cases
    {
        $case->update(['status' => 'archived']);

        $this->clearHubCache($case->hub_id);

        return $case;
    }

    /**
     * Hard delete a case.
     */
    public function destroy(Cases $case): void
    {
        $hubId = $case->hub_id;
        $case->delete();
        $this->clearHubCache($hubId);
    }

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

    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();
        });
    }

    private function clearHubCache(int $hubId): void
    {
        Cache::forget("hub_stats_{$hubId}");
        Cache::forget('hubs.active');
    }
}
