<?php

namespace App\Services;

use App\Models\MexcoCampusApplication;
use App\Models\MexcoEventLicense;
use App\Models\MexcoEventUsage;
use App\Models\MexcoInvoice;
use App\Models\MexcoOrganisation;
use App\Models\MexcoPlan;
use App\Models\MexcoSupportTicket;
use App\Models\MeetupEvent;
use App\Models\MeetupParticipant;
use Illuminate\Support\Collection;

class AnalyticsService
{
    public function __construct(
        private BillingService $billing,
        private CampusService $campus,
    ) {}

    public function platformOverview(): array
    {
        $billing = $this->billing->dashboardStats();
        $campus = $this->campus->dashboardStats();

        $usage = MexcoEventUsage::query()
            ->selectRaw('SUM(participants_count) as participants, SUM(sessions_count) as sessions, SUM(booths_count) as booths')
            ->first();

        return [
            'organisations' => MexcoOrganisation::query()->count(),
            'organisations_active' => MexcoOrganisation::query()->where('status', 'active')->count(),
            'events' => MeetupEvent::query()->count(),
            'events_active' => MeetupEvent::query()->where('platform_status', 'active')->count(),
            'participants' => (int) ($usage->participants ?? MeetupParticipant::query()->count()),
            'sessions' => (int) ($usage->sessions ?? 0),
            'booths' => (int) ($usage->booths ?? 0),
            'open_tickets' => MexcoSupportTicket::query()
                ->whereNotIn('status', [MexcoSupportTicket::STATUS_RESOLVED, MexcoSupportTicket::STATUS_CLOSED])
                ->count(),
            'billing' => $billing,
            'campus' => $campus,
        ];
    }

    public function eventsByPlan(): Collection
    {
        return MexcoEventLicense::query()
            ->join('mexco_plans', 'mexco_plans.id', '=', 'mexco_event_licenses.plan_id')
            ->selectRaw('mexco_plans.code, mexco_plans.name, COUNT(*) as total')
            ->groupBy('mexco_plans.code', 'mexco_plans.name')
            ->orderBy('mexco_plans.sort_order')
            ->get();
    }

    public function revenueByMonth(int $months = 6): Collection
    {
        return MexcoInvoice::query()
            ->where('status', MexcoInvoice::STATUS_PAID)
            ->where('paid_at', '>=', now()->subMonths($months)->startOfMonth())
            ->get()
            ->groupBy(fn ($invoice) => $invoice->paid_at->format('Y-m'))
            ->map(fn ($group, $month) => (object) [
                'month' => $month,
                'total_cents' => $group->sum('total_cents'),
            ])
            ->sortKeys()
            ->values();
    }

    public function topEventsByParticipants(int $limit = 10): Collection
    {
        return MexcoEventUsage::query()
            ->with(['event' => fn ($q) => $q->with('license.plan', 'organisation')])
            ->orderByDesc('participants_count')
            ->limit($limit)
            ->get();
    }

    public function planCatalogue(): Collection
    {
        return MexcoPlan::query()->where('is_active', true)->orderBy('sort_order')->get();
    }
}
