<?php

declare(strict_types=1);

namespace App\Services\Studio;

use App\Models\CollectionComment;
use App\Models\NovaCardComment;
use App\Models\StoryComment;
use App\Models\User;
use App\Support\AvatarUrl;
use Illuminate\Support\Facades\DB;

final class CreatorStudioOverviewService
{
    public function __construct(
        private readonly CreatorStudioContentService $content,
        private readonly CreatorStudioAnalyticsService $analytics,
        private readonly CreatorStudioScheduledService $scheduled,
        private readonly CreatorStudioActivityService $activity,
        private readonly CreatorStudioPreferenceService $preferences,
        private readonly CreatorStudioChallengeService $challenges,
        private readonly CreatorStudioGrowthService $growth,
    ) {
    }

    public function build(User $user): array
    {
        $analytics = $this->analytics->overview($user);
        $moduleSummaries = $this->content->moduleSummaries($user);
        $preferences = $this->preferences->forUser($user);
        $challengeData = $this->challenges->build($user);
        $growthData = $this->growth->build($user, $preferences['analytics_range_days']);
        $featuredContent = $this->content->selectedItems($user, $preferences['featured_content']);

        return [
            'kpis' => [
                'total_content' => $analytics['totals']['content_count'],
                'views_30d' => $analytics['totals']['views'],
                'appreciation_30d' => $analytics['totals']['appreciation'],
                'shares_30d' => $analytics['totals']['shares'],
                'comments_30d' => $analytics['totals']['comments'],
                'followers' => $analytics['totals']['followers'],
            ],
            'module_summaries' => $moduleSummaries,
            'quick_create' => $this->content->quickCreate(),
            'continue_working' => $this->content->continueWorking($user, $preferences['draft_behavior']),
            'scheduled_items' => $this->scheduled->upcoming($user, 5),
            'recent_activity' => $this->activity->recent($user, 6),
            'top_performers' => $analytics['top_content'],
            'recent_comments' => $this->recentComments($user),
            'recent_followers' => $this->recentFollowers($user),
            'draft_reminders' => $this->content->draftReminders($user),
            'stale_drafts' => $this->content->staleDrafts($user),
            'recent_publishes' => $this->content->recentPublished($user, 6),
            'growth_hints' => $this->growthHints($user, $moduleSummaries),
            'active_challenges' => [
                'summary' => $challengeData['summary'],
                'spotlight' => $challengeData['spotlight'],
                'items' => collect($challengeData['active_challenges'] ?? [])->take(3)->values()->all(),
            ],
            'creator_health' => [
                'score' => (int) round(collect($growthData['checkpoints'] ?? [])->avg('score') ?? 0),
                'summary' => $growthData['summary'],
                'checkpoints' => collect($growthData['checkpoints'] ?? [])->take(3)->values()->all(),
            ],
            'featured_status' => $this->featuredStatus($preferences, $featuredContent),
            'workflow_focus' => $this->workflowFocus($user),
            'command_center' => $this->commandCenter($user),
            'insight_blocks' => $analytics['insight_blocks'] ?? [],
            'preferences' => [
                'widget_visibility' => $preferences['widget_visibility'],
                'widget_order' => $preferences['widget_order'],
                'card_density' => $preferences['card_density'],
            ],
        ];
    }

    private function featuredStatus(array $preferences, array $featuredContent): array
    {
        $modules = ['artworks', 'cards', 'collections', 'stories'];
        $selectedModules = array_values(array_filter($modules, fn (string $module): bool => isset($featuredContent[$module]) && is_array($featuredContent[$module])));
        $missingModules = array_values(array_diff($modules, $selectedModules));

        return [
            'selected_count' => count($selectedModules),
            'target_count' => count($modules),
            'featured_modules' => $preferences['featured_modules'],
            'missing_modules' => $missingModules,
            'items' => collect($featuredContent)
                ->filter(fn ($item): bool => is_array($item))
                ->values()
                ->take(4)
                ->all(),
        ];
    }

    private function workflowFocus(User $user): array
    {
        $continue = collect($this->content->continueWorking($user, 'resume-last', 6));

        return [
            'priority_drafts' => $continue
                ->filter(fn (array $item): bool => (bool) ($item['workflow']['is_stale_draft'] ?? false) || ! (bool) ($item['workflow']['readiness']['can_publish'] ?? false))
                ->take(3)
                ->values()
                ->all(),
            'ready_to_schedule' => $continue
                ->filter(fn (array $item): bool => (bool) ($item['workflow']['readiness']['can_publish'] ?? false))
                ->take(3)
                ->values()
                ->all(),
        ];
    }

    private function commandCenter(User $user): array
    {
        $scheduled = collect($this->scheduled->upcoming($user, 16));
        $inbox = collect($this->activity->recent($user, 16));
        $todayStart = now()->startOfDay();
        $todayEnd = now()->endOfDay();

        return [
            'publishing_today' => $scheduled->filter(function (array $item) use ($todayStart, $todayEnd): bool {
                $timestamp = strtotime((string) ($item['scheduled_at'] ?? $item['published_at'] ?? '')) ?: 0;

                return $timestamp >= $todayStart->getTimestamp() && $timestamp <= $todayEnd->getTimestamp();
            })->values()->all(),
            'attention_now' => $inbox->filter(fn (array $item): bool => in_array((string) ($item['type'] ?? ''), ['comment', 'notification'], true))->take(4)->values()->all(),
        ];
    }

    private function growthHints(User $user, array $moduleSummaries): array
    {
        $user->loadMissing('profile');
        $summaries = collect($moduleSummaries)->keyBy('key');
        $hints = [];

        if (blank($user->profile?->bio) || blank($user->profile?->tagline)) {
            $hints[] = [
                'title' => 'Complete your creator profile',
                'body' => 'Add a tagline and bio so your public presence matches the work you are publishing.',
                'url' => route('studio.profile'),
                'label' => 'Update profile',
            ];
        }

        if (((int) ($summaries->get('cards')['count'] ?? 0)) === 0) {
            $hints[] = [
                'title' => 'Publish your first card',
                'body' => 'Cards now live inside Creator Studio, making short-form publishing a first-class workflow.',
                'url' => route('studio.cards.create'),
                'label' => 'Create card',
            ];
        }

        if (((int) ($summaries->get('collections')['count'] ?? 0)) === 0) {
            $hints[] = [
                'title' => 'Create a featured collection',
                'body' => 'Curated collections give your profile a stronger editorial shape and a better publishing shelf.',
                'url' => route('settings.collections.create'),
                'label' => 'Start collection',
            ];
        }

        if (((int) ($summaries->get('artworks')['count'] ?? 0)) === 0) {
            $hints[] = [
                'title' => 'Upload your first artwork',
                'body' => 'Seed the workspace with a first long-form piece so analytics, drafts, and collections have something to build on.',
                'url' => '/upload',
                'label' => 'Upload artwork',
            ];
        }

        return collect($hints)->take(3)->values()->all();
    }

    public function recentComments(User $user, int $limit = 12): array
    {
        $artworkComments = DB::table('artwork_comments')
            ->join('artworks', 'artworks.id', '=', 'artwork_comments.artwork_id')
            ->join('users', 'users.id', '=', 'artwork_comments.user_id')
            ->where('artworks.user_id', $user->id)
            ->whereNull('artwork_comments.deleted_at')
            ->select([
                'artwork_comments.id',
                'artwork_comments.content as body',
                'artwork_comments.created_at',
                'users.name as author_name',
                'artworks.title as item_title',
                'artworks.slug as item_slug',
                'artworks.id as item_id',
            ])
            ->orderByDesc('artwork_comments.created_at')
            ->limit($limit)
            ->get()
            ->map(fn ($row): array => [
                'id' => sprintf('artworks:%d', (int) $row->id),
                'module' => 'artworks',
                'module_label' => 'Artworks',
                'author_name' => $row->author_name,
                'item_title' => $row->item_title,
                'body' => $row->body,
                'created_at' => $this->normalizeDate($row->created_at),
                'context_url' => route('art.show', ['id' => $row->item_id, 'slug' => $row->item_slug]),
            ]);

        $cardComments = NovaCardComment::query()
            ->with(['user:id,name,username', 'card:id,title,slug'])
            ->whereNull('deleted_at')
            ->whereHas('card', fn ($query) => $query->where('user_id', $user->id))
            ->latest('created_at')
            ->limit($limit)
            ->get()
            ->map(fn (NovaCardComment $comment): array => [
                'id' => sprintf('cards:%d', (int) $comment->id),
                'module' => 'cards',
                'module_label' => 'Cards',
                'author_name' => $comment->user?->name ?: $comment->user?->username ?: 'Creator',
                'item_title' => $comment->card?->title,
                'body' => $comment->body,
                'created_at' => $comment->created_at?->toIso8601String(),
                'context_url' => $comment->card ? route('studio.cards.analytics', ['id' => $comment->card->id]) : route('studio.cards.index'),
            ]);

        $collectionComments = CollectionComment::query()
            ->with(['user:id,name,username', 'collection:id,title'])
            ->whereNull('deleted_at')
            ->whereHas('collection', fn ($query) => $query->where('user_id', $user->id))
            ->latest('created_at')
            ->limit($limit)
            ->get()
            ->map(fn (CollectionComment $comment): array => [
                'id' => sprintf('collections:%d', (int) $comment->id),
                'module' => 'collections',
                'module_label' => 'Collections',
                'author_name' => $comment->user?->name ?: $comment->user?->username ?: 'Creator',
                'item_title' => $comment->collection?->title,
                'body' => $comment->body,
                'created_at' => $comment->created_at?->toIso8601String(),
                'context_url' => $comment->collection ? route('settings.collections.show', ['collection' => $comment->collection->id]) : route('studio.collections'),
            ]);

        $storyComments = StoryComment::query()
            ->with(['user:id,name,username', 'story:id,title'])
            ->whereNull('deleted_at')
            ->where('is_approved', true)
            ->whereHas('story', fn ($query) => $query->where('creator_id', $user->id))
            ->latest('created_at')
            ->limit($limit)
            ->get()
            ->map(fn (StoryComment $comment): array => [
                'id' => sprintf('stories:%d', (int) $comment->id),
                'module' => 'stories',
                'module_label' => 'Stories',
                'author_name' => $comment->user?->name ?: $comment->user?->username ?: 'Creator',
                'item_title' => $comment->story?->title,
                'body' => $comment->content,
                'created_at' => $comment->created_at?->toIso8601String(),
                'context_url' => $comment->story ? route('creator.stories.analytics', ['story' => $comment->story->id]) : route('studio.stories'),
            ]);

        return $artworkComments
            ->concat($cardComments)
            ->concat($collectionComments)
            ->concat($storyComments)
            ->sortByDesc(fn (array $comment): int => $this->timestamp($comment['created_at'] ?? null))
            ->take($limit)
            ->values()
            ->all();
    }

    public function recentFollowers(User $user, int $limit = 8): array
    {
        return DB::table('user_followers as uf')
            ->join('users as follower', 'follower.id', '=', 'uf.follower_id')
            ->leftJoin('user_profiles as profile', 'profile.user_id', '=', 'follower.id')
            ->where('uf.user_id', $user->id)
            ->whereNull('follower.deleted_at')
            ->orderByDesc('uf.created_at')
            ->limit($limit)
            ->get([
                'follower.id',
                'follower.username',
                'follower.name',
                'profile.avatar_hash',
                'uf.created_at',
            ])
            ->map(fn ($row): array => [
                'id' => (int) $row->id,
                'name' => $row->name ?: '@' . $row->username,
                'username' => $row->username,
                'profile_url' => '/@' . strtolower((string) $row->username),
                'avatar_url' => AvatarUrl::forUser((int) $row->id, $row->avatar_hash, 64),
                'created_at' => $this->normalizeDate($row->created_at),
            ])
            ->values()
            ->all();
    }

    private function normalizeDate(mixed $value): ?string
    {
        if ($value instanceof \DateTimeInterface) {
            return $value->format(DATE_ATOM);
        }

        if (is_string($value) && $value !== '') {
            return $value;
        }

        return null;
    }

    private function timestamp(mixed $value): int
    {
        if (! is_string($value) || $value === '') {
            return 0;
        }

        return strtotime($value) ?: 0;
    }
}