<?php

namespace App\Http\Services;

use App\Models\SocialAccount;
use App\Models\SocialPost;

class AnalyticsService
{
    public function getPostSummary(): array
    {
        $currentPeriodPosts = SocialPost::filterByContext()
            ->with('metrics')
            ->where('created_at', '>=', now()->subDays(30));

        $previousPeriodPosts = SocialPost::filterByContext()
            ->with('metrics')
            ->whereBetween('created_at', [now()->subDays(60), now()->subDays(30)]);

        // Totals
        $totalPosts = $currentPeriodPosts->count();
        $totalReach = $currentPeriodPosts->get()->sum(fn($post) => $post->metrics->impressions ?? 0);
        $totalEngagement = $currentPeriodPosts->get()->sum(fn($post) => $post->metrics->engagements ?? 0);

        $prevTotalPosts = $previousPeriodPosts->count();
        $prevTotalReach = $previousPeriodPosts->get()->sum(fn($post) => $post->metrics->impressions ?? 0);
        $prevTotalEngagement = $previousPeriodPosts->get()->sum(fn($post) => $post->metrics->engagements ?? 0);

        $avgEngagementRate = $totalReach > 0 ? round(($totalEngagement / $totalReach) * 100, 2) : 0;
        $prevAvgEngagementRate = $prevTotalReach > 0 ? round(($prevTotalEngagement / $prevTotalReach) * 100, 2) : 0;

        $calculateChange = fn($current, $previous) => match(true) {
            $previous > 0 => round((($current - $previous) / $previous) * 100, 2),
            $current > 0 => 100, // If previous is 0 but current has data, show 100% growth
            default => 0,
        };

        $formatMetric = fn($title, $current, $previous, $isPercentage = false) => [
            'title' => $title,
            'label' => 'Last 30 days',
            'dataKey' => lcfirst(str_replace(' ', '', $title)),
            'change' => $calculateChange($current, $previous) . '%',
            'changeType' => $current >= $previous ? 'increase' : 'decrease',
            'color' => $current >= $previous ? 'text-green-500' : 'text-red-500',
            'isPercentage' => $isPercentage,
        ];

        return [
            'totalPosts' => $totalPosts,
            'totalReach' => $totalReach,
            'totalEngagement' => $totalEngagement,
            'avgEngagementRate' => $avgEngagementRate,
            'metrics' => [
                $formatMetric('Total Posts', $totalPosts, $prevTotalPosts),
                $formatMetric('Total Reach', $totalReach, $prevTotalReach),
                $formatMetric('Total Engagement', $totalEngagement, $prevTotalEngagement),
                $formatMetric('Avg Engagement Rate', $avgEngagementRate, $prevAvgEngagementRate, true),
            ],
        ];
    }

    public function getTopPosts(): array
    {
        $posts = SocialPost::filterByContext()
            ->with(['account', 'platform', 'files', 'metrics'])
            ->whereNotNull('created_at')
            ->orderByDesc('created_at')
            ->get();

        if ($posts->isEmpty()) {
            return [];
        }

        $hasEngagement = $posts->contains(fn($post) => ($post->metrics->engagements ?? 0) > 0);

        $sorted = $hasEngagement
            ? $posts->sortByDesc(fn($post) => $post->metrics->engagements ?? 0)
            : $posts->sortByDesc('created_at');

        return $sorted->take(5)->map(function ($post) {
            return [
                'id' => $post->id,
                'author' => $post->account->name ?? 'Unknown',
                'platform' => $post->platform ?? [],
                'publishDate' => optional($post->created_at)->format('M d, Y'),
                'content' => \Str::limit($post->content, 80),
                'media' => $post->files->map(fn($file) => [
                    'id' => $file->id,
                    'url' => imageURL($file, 'gallery'),
                    'thumbnail' => imageURL($file, 'gallery'),
                    'alt' => $file->pivot->alt ?? $file->name,
                    'isVideo' => (getFileTypeFromExtension($file->extension) == 'video'),
                ])->toArray(),
                'engagement' => [
                    'reactions' => $post->metrics->reactions ?? 0,
                    'comments' => $post->metrics->comments ?? 0,
                    'shares' => $post->metrics->shares ?? 0,
                ],
                'analytics' => [
                    'impressions' => number_format($post->metrics->impressions ?? 0),
                    'engagement' => number_format($post->metrics->engagements ?? 0),
                ],
            ];
        })->values()->toArray();
    }

    public function getEngagementAnalytics(): array
    {
        $dailyEngagement = SocialPost::filterByContext()
            ->with('metrics')
            ->get()
            ->groupBy(fn($post) => $post->created_at->format('M'))
            ->map(function ($posts, $month) {
                return [
                    'month' => $month,
                    'likes' => $posts->sum(fn($p) => optional($p->metrics)->likes ?? 0),
                    'comments' => $posts->sum(fn($p) => optional($p->metrics)->comments ?? 0),
                    'shares' => $posts->sum(fn($p) => optional($p->metrics)->shares ?? 0),
                ];
            })
            ->values()
            ->toArray();

        $daily = SocialPost::filterByContext()
            ->with('metrics')
            ->get()
            ->groupBy(fn($post) => $post->created_at->format('Y-m-d'))
            ->map(function ($posts, $date) {
                return [
                    'date' => $date,
                    'likes' => $posts->sum(fn($p) => optional($p->metrics)->likes ?? 0),
                    'comments' => $posts->sum(fn($p) => optional($p->metrics)->comments ?? 0),
                    'shares' => $posts->sum(fn($p) => optional($p->metrics)->shares ?? 0),
                ];
            })
            ->values()
            ->toArray();

        return [
            'dailyEngagement' => $dailyEngagement,
            'daily' => $daily,
        ];
    }

    public function getAccountPerformance(): array
    {
        $platformSlug = request('slug');
        $user = auth_user();
        $workspace = current_workspace();

        $accountsQuery = SocialAccount::query()
            ->with([
                'posts' => fn($q) => $q->filterByContext(),
                'posts.metrics'
            ])
            ->where('user_id', $user?->id)
            ->when($workspace, fn($q) => $q->where('workspace_id', $workspace->id))
            ->when(
                $platformSlug,
                fn($q) =>
                $q->whereHas('platform', fn($q2) => $q2->where('slug', $platformSlug))
            )
            ->whereNotNull('name')
            ->where('name', '!=', '');

        $accounts = $accountsQuery->get();

        // Aggregate metrics
        $followers = $accounts->sum('followers');
        $following = $accounts->sum('following');
        $postsCount = $accounts->sum(fn($a) => $a->posts->count());

        // Engagement %
        $totalEngagement = $accounts->sum(fn($a) => $a->posts->sum(
            fn($p) =>
            (optional($p->metrics)->likes ?? 0)
            + (optional($p->metrics)->comments ?? 0)
            + (optional($p->metrics)->shares ?? 0)
        ));

        $engagementRate = $followers > 0 ? round(($totalEngagement / $followers) * 100, 2) : 0;

        // Growth by month (fake snapshots for now)
        $growth = [];
        $months = now()->subMonths(2)->startOfMonth()->monthsUntil(now()->startOfMonth());
        foreach ($months as $month) {
            $monthlyFollowers = $accounts->sum(fn($a) => $a->followers);
            $growth[] = [
                'month' => $month->format('M'),
                'followers' => $monthlyFollowers,
            ];
        }

        // Top accounts by followers
        $topAccounts = $accounts->sortByDesc('followers')->take(7)->map(fn($a) => [
            'name' => $a->name,
            'followers' => number_format($a->followers / 1000, 2) . 'k',
            'percentage' => $followers > 0 ? round(($a->followers / $followers) * 100, 2) : 0,
            'value' => $followers > 0 ? round(($a->followers / $followers) * 100, 2) : 0,
        ])->values()->toArray();

        return [
            'followers' => $followers,
            'following' => $following,
            'posts' => $postsCount,
            'engagement' => $engagementRate,
            'growth' => $growth,
            'accounts' => $topAccounts,
        ];
    }

    public function getAllContents(): array
    {
        $posts = SocialPost::filterByContext()
            ->with(['account', 'metrics', 'files', 'platform'])
            ->latest()
            ->get()
            ->groupBy('post_type')
            ->map(fn($group) => $group->take(3))
            ->flatten();

        return [
            'posts' => $posts->map(fn($post) => [
                'id' => $post->id,
                'type' => $post->post_type?->name ?? 'post',
                'platform' => $post->platform,
                'author' => $post->account?->name ?? 'Unknown',
                'timestamp' => optional($post->created_at)->format('M d, Y h:ia'),
                'content' => $post->content,
                'media' => $post->files->map(fn($file) => [
                    'id' => $file->id,
                    'url' => imageURL($file, 'gallery'),
                    'thumbnail' => imageURL($file, 'gallery'),
                    'alt' => $file->pivot->alt ?? $file->name,
                    'isVideo' => (getFileTypeFromExtension($file->extension) == 'video'),
                ])->toArray(),
                'metrics' => [
                    'impression' => optional($post->metrics)->impressions ?? 0,
                    'engagement' => optional($post->metrics)->engagements ?? 0,
                    'clicks' => optional($post->metrics)->clicks ?? 0,
                    'shares' => optional($post->metrics)->shares ?? 0,
                    'comments' => optional($post->metrics)->comments ?? 0,
                    'conversions' => optional($post->metrics)->conversions ?? 0,
                    'bounceRate' => optional($post->metrics)->bounce_rate ?? '0%',
                    'newFollowers' => optional($post->metrics)->new_followers ?? 0,
                    'revenue' => optional($post->metrics)->revenue ?? '$0',
                ],
            ])->toArray(),
        ];
    }

    public function getAudienceByAge(): array
    {
        return [
            ['ageRange' => "10-20", 'percentage' => 15],
            ['ageRange' => "21-30", 'percentage' => 75],
            ['ageRange' => "31-40", 'percentage' => 42],
            ['ageRange' => "41-50", 'percentage' => 14],
            ['ageRange' => "51-70", 'percentage' => 10],
        ];
    }

    public function getGeoDistribution(): array
    {
        return [
            'countries' => [
                ["Country", "Visitors"],
                ["United States", 35],
                ["Canada", 25],
                ["Indonesia", 55],
            ],
            'statistics' => [
                ['region' => "Indonesia", 'percentage' => 35, 'color' => "blue"],
                ['region' => "North America", 'percentage' => 55, 'color' => "blue"],
            ],
        ];
    }

    public function getStatisticByGender(): array
    {
        return [
            ['gender' => "Female", 'percentage' => 72, 'color' => "#1E90FF"],
            ['gender' => "Male", 'percentage' => 28, 'color' => "#E5E7EB"],
        ];
    }

    public function getSocialAccounts()
    {
        $user = auth_user();
        $workspace = current_workspace();

        return SocialAccount::with("platform")
            ->where('user_id', $user?->id)
            ->when($workspace, fn($q) => $q->where('workspace_id', $workspace->id))
            ->filterByPlatform()
            ->whereNotNull('name')
            ->where('name', '!=', '')
            ->latest()
            ->take(6)
            ->get();
    }

    /**
     * Master method: build full unified analytical data
     */
    public function getAnalytics(): array
    {
        return [
            'postSummary' => $this->getPostSummary(),
            'topPosts' => $this->getTopPosts(),
            'engagementAnalytics' => $this->getEngagementAnalytics(),
            'accountPerformance' => $this->getAccountPerformance(),
            'allContents' => $this->getAllContents(),
            'audienceByAge' => $this->getAudienceByAge(),
            'geoDistribution' => $this->getGeoDistribution(),
            'statisticByGender' => $this->getStatisticByGender(),
            'socialAccounts' => $this->getSocialAccounts()
        ];
    }
}
