<?php

namespace App\Services\Member;

use App\Models\Document;
use App\Models\DocumentRating;
use App\Models\ForumPost;
use App\Models\Hub;
use App\Models\Sector;
use App\Models\User;
use Illuminate\Http\UploadedFile;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

// ══════════════════════════════════════════════════════════════════
//  InPractice — ShareKnowledgeService
//  Location: app/Services/Member/ShareKnowledgeService.php
//
//  Handles both Share Knowledge paths:
//    Path 1 — Text post (knowledge_share post_type on forum_posts)
//    Path 2 — PDF document upload (documents table)
//
//  Follows Bible strictly:
//    - All business logic here, zero in controller
//    - DB transactions on writes
//    - Eager loading always
//    - Pagination always (posts: 20/page, documents: 15/page)
//    - Cache cleared on every write
//    - File stored as UUID, never original filename
// ══════════════════════════════════════════════════════════════════

class ShareKnowledgeService
{
    // ══════════════════════════════════════════════════════════════
    //  INDEX — combined feed of posts + documents for a hub
    // ══════════════════════════════════════════════════════════════

    public function index(User $user, array $filters = []): array
    {
        $hubId  = (int) ($filters['hub_id'] ?? 0);
        $type   = $filters['type']   ?? 'all';   // all | post | document
        $search = trim($filters['search'] ?? '');

        $allHubs = Cache::remember('hubs.active', 3600, fn () =>
            Hub::where('is_active', true)->get(['id', 'name_en', 'name_ar', 'color', 'icon'])
        );

        if (! $hubId) {
            $primaryHub = $user->primaryHub?->hub_id;
            $hubId = $primaryHub ?? $allHubs->first()?->id ?? 0;
        }

        $sectors = Cache::remember('sectors.all', 3600, fn () =>
            Sector::orderBy('name_en')->get(['id', 'name_en', 'name_ar'])
        );

        // ── Text posts (knowledge_share type) ─────────────────
        $postsQuery = ForumPost::with([
                'user:id,nickname,profession',
                'hub:id,name_en,name_ar,color',
            ])
            ->visible()
            ->where('status', '!=', 'removed')
            ->where('post_type', 'knowledge_share');

        if ($hubId) {
            $postsQuery->where('hub_id', $hubId);
        }

        if ($search) {
            $postsQuery->where(function ($q) use ($search) {
                $q->where('title', 'like', "%{$search}%")
                  ->orWhere('body', 'like', "%{$search}%");
            });
        }

        // ── PDF documents ──────────────────────────────────────
        $userHubIds = $user->hubs->pluck('id')->toArray();

        $docsQuery = Document::with([
                'user:id,nickname,profession',
                'hub:id,name_en,name_ar,color',
                'sector:id,name_en,name_ar',
            ])
            ->approved()
            ->visible($userHubIds);

        if ($hubId) {
            $docsQuery->where('hub_id', $hubId);
        }

        if ($search) {
            $docsQuery->where(function ($q) use ($search) {
                $q->where('title_en', 'like', "%{$search}%")
                  ->orWhere('title_ar', 'like', "%{$search}%")
                  ->orWhere('description_en', 'like', "%{$search}%");
            });
        }

        // Return separate paginated results based on type filter
        $posts     = ($type === 'document') ? collect() : $postsQuery->orderByDesc('created_at')->paginate(20)->withQueryString();
        $documents = ($type === 'post')     ? collect() : $docsQuery->orderByDesc('created_at')->paginate(15)->withQueryString();

        // Format posts for Vue
        if ($type !== 'document' && $posts instanceof LengthAwarePaginator) {
            $posts->getCollection()->transform(fn ($post) => $this->formatPost($post, $user));
        }

        // Format documents for Vue
        if ($type !== 'post' && $documents instanceof LengthAwarePaginator) {
            $documents->getCollection()->transform(fn ($doc) => $this->formatDocument($doc, $user));
        }

        return [
            'posts'       => $posts,
            'documents'   => $documents,
            'allHubs'     => $allHubs->values()->toArray(),
            'sectors'     => $sectors->values()->toArray(),
            'activeHubId' => $hubId,
            'filters'     => [
                'hub_id' => $hubId,
                'type'   => $type,
                'search' => $search,
            ],
        ];
    }

    public function createDocument(): array
    {
        $allHubs = Cache::remember('hubs.active', 3600, fn () =>
            Hub::where('is_active', true)
                ->get(['id', 'name_en', 'name_ar', 'color', 'icon'])
        );

        $sectors = Cache::remember('sectors.all', 3600, fn () =>
            Sector::orderBy('name_en')
                ->get(['id', 'name_en', 'name_ar'])
        );

        return [
            'allHubs' => $allHubs->values()->toArray(),
            'sectors' => $sectors->values()->toArray(),
        ];
    }

    public function deleteDocument(User $user, Document $document): void
    {
        abort_if($document->user_id !== $user->id, 403);
        Storage::disk('public')->delete($document->file_path);
        $document->delete();
    }

    // ══════════════════════════════════════════════════════════════
    //  CREATE POST — Share Knowledge text post
    // ══════════════════════════════════════════════════════════════

    public function createPost(User $user, array $data): ForumPost
    {
        return DB::transaction(function () use ($user, $data) {
            $post = ForumPost::create([
                'user_id'            => $user->id,
                'hub_id'             => $data['hub_id'],
                'post_type'          => 'knowledge_share',
                'title'              => $data['title'],
                'body'               => $data['body'],
                'source_url'         => $data['source_url'] ?? null,
                'source_label'       => $data['source_label'] ?? null,
                'language'           => $data['language'],
                'visibility'         => $data['visibility'],
                'posted_as_nickname' => $data['posted_as_nickname'] ?? true,
                'tags'               => $data['tags'] ?? [],
                'status'             => 'active',
            ]);

            // Clear hub stats cache — post count changed
            Cache::forget("hub.{$data['hub_id']}.stats");

            return $post;
        });
    }

    // ══════════════════════════════════════════════════════════════
    //  UPLOAD DOCUMENT — Share Knowledge PDF upload
    // ══════════════════════════════════════════════════════════════

    public function uploadDocument(User $user, array $data, UploadedFile $file): Document
    {
        return DB::transaction(function () use ($user, $data, $file) {
            // Bible: store as UUID — never original filename on disk
            $filename = Str::uuid() . '.pdf';
            $path     = $file->storeAs('documents', $filename, 'public');

            $document = Document::create([
                'user_id'           => $user->id,
                'hub_id'            => $data['hub_id'],
                'original_filename' => $file->getClientOriginalName(),
                'stored_filename'   => $filename,
                'file_path'         => $path,
                'file_type'         => 'pdf',
                'file_size'         => $file->getSize(),
                'title_en'          => $data['title_en'],
                'title_ar'          => $data['title_ar'] ?? null,
                'description_en'    => $data['description_en'] ?? null,
                'description_ar'    => $data['description_ar'] ?? null,
                'language'          => $data['language'],
                'document_category' => $data['document_category'],
                'tags'              => $data['tags'] ?? [],
                'sector_id'         => $data['sector_id'] ?? null,
                'visibility'        => $data['visibility'],
                'status'            => 'approved', // auto-approved for MVP — admin can reject later
            ]);

            Cache::forget("hub.{$data['hub_id']}.stats");

            return $document;
        });
    }

    // ══════════════════════════════════════════════════════════════
    //  SHOW DOCUMENT — single document detail page
    // ══════════════════════════════════════════════════════════════

    public function showDocument(User $user, Document $document): array
    {
        abort_if($document->status === 'rejected', 404);

        // Check hub visibility
        if ($document->visibility === 'hub') {
            $userHubIds = $user->hubs->pluck('id')->toArray();
            abort_if(! in_array($document->hub_id, $userHubIds), 403);
        }

        $document->load([
            'user:id,nickname,profession',
            'hub:id,name_en,name_ar,color',
            'sector:id,name_en,name_ar',
        ]);

        // My rating on this document
        $myRating = DocumentRating::where('document_id', $document->id)
            ->where('user_id', $user->id)
            ->value('rating');

        return [
            'document' => $this->formatDocument($document, $user),
            'myRating' => $myRating,
        ];
    }

    // ══════════════════════════════════════════════════════════════
    //  DOWNLOAD — increment counter and return file path
    // ══════════════════════════════════════════════════════════════

    public function download(User $user, Document $document): string
    {
        abort_if($document->status === 'rejected', 404);

        $document->incrementDownloads();

        return Storage::disk('public')->path($document->file_path);
    }

    // ══════════════════════════════════════════════════════════════
    //  RATE DOCUMENT — 1–5 stars, one per member
    // ══════════════════════════════════════════════════════════════

    public function rateDocument(User $user, Document $document, int $rating): array
    {
        abort_if($document->user_id === $user->id, 403); // cannot rate own document

        DB::transaction(function () use ($user, $document, $rating) {
            DocumentRating::updateOrCreate(
                ['user_id' => $user->id, 'document_id' => $document->id],
                ['rating'  => $rating]
            );

            // Recalculate cached average
            $avg   = DocumentRating::where('document_id', $document->id)->avg('rating');
            $count = DocumentRating::where('document_id', $document->id)->count();

            $document->update([
                'rating_average' => round($avg, 2),
                'rating_count'   => $count,
            ]);
        });

        return [
            'rating_average' => $document->fresh()->rating_average,
            'rating_count'   => $document->fresh()->rating_count,
            'my_rating'      => $rating,
        ];
    }

    // ══════════════════════════════════════════════════════════════
    //  PRIVATE HELPERS
    // ══════════════════════════════════════════════════════════════

    private function formatPost(ForumPost $post, User $user): array
    {
        return [
            'id'                 => $post->id,
            'post_type'          => $post->post_type,
            'title'              => $post->title,
            'body'               => $post->body,
            'source_url'         => $post->source_url
                                        ? route('member.share.external', ['url' => $post->source_url])
                                        : null,
            'source_label'       => $post->source_label,
            'language'           => $post->language,
            'visibility'         => $post->visibility,
            'posted_as_nickname' => $post->posted_as_nickname,
            'tags'               => $post->tags ?? [],
            'status'             => $post->status,
            'reply_count'        => $post->reply_count,
            'like_count'         => $post->like_count,
            'view_count'         => $post->view_count,
            'is_pinned'          => $post->is_pinned,
            'is_owner'           => $post->user_id === $user->id,
            'author'             => [
                'nickname'   => $post->posted_as_nickname
                                    ? $post->user->nickname
                                    : ($post->user->show_real_name ? $post->user->name : $post->user->nickname),
                'profession' => $post->user->profession,
            ],
            'hub' => [
                'id'      => $post->hub->id,
                'name_en' => $post->hub->name_en,
                'name_ar' => $post->hub->name_ar,
                'color'   => $post->hub->color,
            ],
            'created_at'         => $post->created_at->diffForHumans(),
            'created_at_full'    => $post->created_at->toDateTimeString(),
            'show_url'           => route('member.forum.show', $post->id),
        ];
    }

    private function formatDocument(Document $document, User $user): array
    {
        return [
            'id'                => $document->id,
            'title_en'          => $document->title_en,
            'title_ar'          => $document->title_ar,
            'description_en'    => $document->description_en,
            'description_ar'    => $document->description_ar,
            'document_category' => $document->document_category,
            'file_size'         => $document->file_size_formatted,
            'language'          => $document->language,
            'tags'              => $document->tags ?? [],
            'visibility'        => $document->visibility,
            'download_count'    => $document->download_count,
            'rating_average'    => $document->rating_average,
            'rating_count'      => $document->rating_count,
            'is_owner'          => $document->user_id === $user->id,
            'author' => [
                'nickname'   => $document->user->nickname,
                'profession' => $document->user->profession,
            ],
            'hub' => [
                'id'      => $document->hub->id,
                'name_en' => $document->hub->name_en,
                'name_ar' => $document->hub->name_ar,
                'color'   => $document->hub->color,
            ],
            'sector' => $document->sector ? [
                'id'      => $document->sector->id,
                'name_en' => $document->sector->name_en,
                'name_ar' => $document->sector->name_ar,
            ] : null,
            'created_at'      => $document->created_at->diffForHumans(),
            'created_at_full' => $document->created_at->toDateTimeString(),
            'download_url'    => route('member.share.document.download', $document->id),
            'preview_url'     => route('member.share.document.preview', $document->id),
            'show_url'        => route('member.share.document.show', $document->id),
        ];
    }
}