<?php

declare(strict_types=1);

namespace App\Services\Studio;

use App\Models\User;
use App\Services\Studio\Contracts\CreatorStudioProvider;
use Illuminate\Support\Facades\DB;
use function collect;
use function now;

final class CreatorStudioAnalyticsService
{
    public function __construct(
        private readonly CreatorStudioContentService $content,
    ) {
    }

    public function overview(User $user, int $days = 30): array
    {
        $providers = collect($this->content->providers());
        $moduleBreakdown = $providers->map(function (CreatorStudioProvider $provider) use ($user): array {
            $summary = $provider->summary($user);
            $analytics = $provider->analytics($user);

            return [
                'key' => $provider->key(),
                'label' => $provider->label(),
                'icon' => $provider->icon(),
                'count' => $summary['count'],
                'draft_count' => $summary['draft_count'],
                'published_count' => $summary['published_count'],
                'archived_count' => $summary['archived_count'],
                'views' => $analytics['views'],
                'appreciation' => $analytics['appreciation'],
                'shares' => $analytics['shares'],
                'comments' => $analytics['comments'],
                'saves' => $analytics['saves'],
                'index_url' => $provider->indexUrl(),
            ];
        })->values();

        $followers = (int) DB::table('user_followers')->where('user_id', $user->id)->count();

        $totals = [
            'views' => (int) $moduleBreakdown->sum('views'),
            'appreciation' => (int) $moduleBreakdown->sum('appreciation'),
            'shares' => (int) $moduleBreakdown->sum('shares'),
            'comments' => (int) $moduleBreakdown->sum('comments'),
            'saves' => (int) $moduleBreakdown->sum('saves'),
            'followers' => $followers,
            'content_count' => (int) $moduleBreakdown->sum('count'),
        ];

        $topContent = $providers
            ->flatMap(fn (CreatorStudioProvider $provider) => $provider->topItems($user, 4))
            ->sortByDesc(fn (array $item): int => (int) ($item['engagement_score'] ?? 0))
            ->take(8)
            ->values()
            ->all();

        return [
            'totals' => $totals,
            'module_breakdown' => $moduleBreakdown->all(),
            'top_content' => $topContent,
            'views_trend' => $this->trendSeries($user, $days, 'views'),
            'engagement_trend' => $this->trendSeries($user, $days, 'engagement'),
            'publishing_timeline' => $this->publishingTimeline($user, $days),
            'comparison' => $this->comparison($user, $days),
            'insight_blocks' => $this->insightBlocks($moduleBreakdown, $totals, $days),
            'range_days' => $days,
        ];
    }

    private function insightBlocks($moduleBreakdown, array $totals, int $days): array
    {
        $strongest = $moduleBreakdown->sortByDesc('appreciation')->first();
        $busiest = $moduleBreakdown->sortByDesc('count')->first();
        $conversation = $moduleBreakdown->sortByDesc('comments')->first();

        $insights = [];

        if ($strongest) {
            $insights[] = [
                'key' => 'strongest_module',
                'title' => $strongest['label'] . ' is driving the strongest reaction',
                'body' => sprintf(
                    '%s generated %s reactions in the last %d days, making it the strongest appreciation surface in Studio right now.',
                    $strongest['label'],
                    number_format((int) $strongest['appreciation']),
                    $days,
                ),
                'tone' => 'positive',
                'icon' => 'fa-solid fa-sparkles',
                'href' => $strongest['index_url'],
                'cta' => 'Open module',
            ];
        }

        if ($conversation && (int) ($conversation['comments'] ?? 0) > 0) {
            $insights[] = [
                'key' => 'conversation_module',
                'title' => 'Conversation is concentrating in ' . $conversation['label'],
                'body' => sprintf(
                    '%s collected %s comments in this window. That is the clearest place to check for follow-up and community signals.',
                    $conversation['label'],
                    number_format((int) $conversation['comments']),
                ),
                'tone' => 'action',
                'icon' => 'fa-solid fa-comments',
                'href' => route('studio.inbox', ['module' => $conversation['key'], 'type' => 'comment']),
                'cta' => 'Open inbox',
            ];
        }

        if ($busiest && (int) ($busiest['draft_count'] ?? 0) > 0) {
            $insights[] = [
                'key' => 'draft_pressure',
                'title' => $busiest['label'] . ' has the heaviest backlog',
                'body' => sprintf(
                    '%s currently has %s drafts. That is the best candidate for your next cleanup, publish, or scheduling pass.',
                    $busiest['label'],
                    number_format((int) $busiest['draft_count']),
                ),
                'tone' => 'warning',
                'icon' => 'fa-solid fa-layer-group',
                'href' => route('studio.drafts', ['module' => $busiest['key']]),
                'cta' => 'Review drafts',
            ];
        }

        if ((int) ($totals['followers'] ?? 0) > 0) {
            $insights[] = [
                'key' => 'audience_presence',
                'title' => 'Audience footprint is active across the workspace',
                'body' => sprintf(
                    'You now have %s followers connected to this creator profile. Keep featured content and your publishing cadence aligned with that audience.',
                    number_format((int) $totals['followers']),
                ),
                'tone' => 'neutral',
                'icon' => 'fa-solid fa-user-group',
                'href' => route('studio.featured'),
                'cta' => 'Manage featured',
            ];
        }

        return collect($insights)->take(4)->values()->all();
    }

    private function publishingTimeline(User $user, int $days): array
    {
        $timeline = collect(range($days - 1, 0))->map(function (int $offset): array {
            $date = now()->subDays($offset)->startOfDay();

            return [
                'date' => $date->toDateString(),
                'count' => 0,
            ];
        })->keyBy('date');

        collect($this->content->recentPublished($user, 120))
            ->each(function (array $item) use ($timeline): void {
                $publishedAt = $item['published_at'] ?? $item['updated_at'] ?? null;
                if (! $publishedAt) {
                    return;
                }

                $date = date('Y-m-d', strtotime((string) $publishedAt));
                if (! $timeline->has($date)) {
                    return;
                }

                $row = $timeline->get($date);
                $row['count']++;
                $timeline->put($date, $row);
            });

        return $timeline->values()->all();
    }

    private function trendSeries(User $user, int $days, string $metric): array
    {
        $series = collect(range($days - 1, 0))->map(function (int $offset): array {
            $date = now()->subDays($offset)->toDateString();

            return [
                'date' => $date,
                'value' => 0,
            ];
        })->keyBy('date');

        collect($this->content->providers())
            ->flatMap(fn (CreatorStudioProvider $provider) => $provider->items($user, 'all', 240))
            ->each(function (array $item) use ($series, $metric): void {
                $dateSource = $item['published_at'] ?? $item['updated_at'] ?? $item['created_at'] ?? null;
                if (! $dateSource) {
                    return;
                }

                $date = date('Y-m-d', strtotime((string) $dateSource));
                if (! $series->has($date)) {
                    return;
                }

                $row = $series->get($date);
                $increment = $metric === 'views'
                    ? (int) ($item['metrics']['views'] ?? 0)
                    : (int) ($item['engagement_score'] ?? 0);
                $row['value'] += $increment;
                $series->put($date, $row);
            });

        return $series->values()->all();
    }

    private function comparison(User $user, int $days): array
    {
        $windowStart = now()->subDays($days)->getTimestamp();

        return collect($this->content->providers())
            ->map(function (CreatorStudioProvider $provider) use ($user, $windowStart): array {
                $items = $provider->items($user, 'all', 240)
                    ->filter(function (array $item) use ($windowStart): bool {
                        $date = $item['published_at'] ?? $item['updated_at'] ?? $item['created_at'] ?? null;

                        return $date !== null && strtotime((string) $date) >= $windowStart;
                    });

                return [
                    'key' => $provider->key(),
                    'label' => $provider->label(),
                    'icon' => $provider->icon(),
                    'views' => (int) $items->sum(fn (array $item): int => (int) ($item['metrics']['views'] ?? 0)),
                    'engagement' => (int) $items->sum(fn (array $item): int => (int) ($item['engagement_score'] ?? 0)),
                    'published_count' => (int) $items->filter(fn (array $item): bool => ($item['status'] ?? null) === 'published')->count(),
                ];
            })
            ->values()
            ->all();
    }
}