<?php

namespace App\Http\Controllers\SuperAdmin;

use App\Http\Controllers\Controller;
use App\Models\Booking;
use App\Models\Company;
use App\Models\Plan;
use App\Models\Subscription;
use App\Models\SubscriptionPayment;
use Illuminate\Support\Carbon;
use Illuminate\View\View;

class DashboardController extends Controller
{
    public function index(): View
    {
        $now = now();
        $startOfMonth     = $now->copy()->startOfMonth();
        $prevMonthStart   = $now->copy()->subMonth()->startOfMonth();
        $prevMonthEnd     = $now->copy()->subMonth()->endOfMonth();

        $companiesNow  = Company::count();
        $companiesPrev = Company::where('created_at', '<', $startOfMonth)->count();
        $companyTrend  = $this->trend($companiesNow, $companiesPrev);

        $mrrNow  = (float) SubscriptionPayment::paid()->whereBetween('paid_at', [$startOfMonth, $now])->sum('amount');
        $mrrPrev = (float) SubscriptionPayment::paid()->whereBetween('paid_at', [$prevMonthStart, $prevMonthEnd])->sum('amount');
        $mrrTrend = $this->trend($mrrNow, $mrrPrev);

        $bookingsNow  = Booking::whereBetween('created_at', [$startOfMonth, $now])->count();
        $bookingsPrev = Booking::whereBetween('created_at', [$prevMonthStart, $prevMonthEnd])->count();
        $bookingsTrend= $this->trend($bookingsNow, $bookingsPrev);

        $kpis = [
            'companies_total'     => $companiesNow,
            'companies_trend'     => $companyTrend,
            'companies_active'    => Company::active()->count(),
            'companies_trial'     => Company::where('status', 'trial')->count(),
            'companies_suspended' => Company::suspended()->count(),
            'subs_active'         => Subscription::active()->count(),
            'subs_expiring'       => Subscription::expiringSoon(7)->count(),
            'mrr'                 => $mrrNow,
            'mrr_trend'           => $mrrTrend,
            'bookings_month'      => $bookingsNow,
            'bookings_trend'      => $bookingsTrend,
        ];

        // Sparklines (últimos 14 días)
        $sparkCompanies = $this->dailyCount(Company::query(), 'created_at', 14);
        $sparkBookings  = $this->dailyCount(Booking::query(), 'created_at', 14);
        $sparkRevenue   = $this->dailySum(SubscriptionPayment::paid(), 'paid_at', 'amount', 14);

        // Chart principal: ingresos últimos 6 meses
        $revenueSeries = [];
        $revenueCats   = [];
        for ($i = 5; $i >= 0; $i--) {
            $m = $now->copy()->subMonths($i);
            $revenueCats[]   = $m->isoFormat('MMM');
            $revenueSeries[] = (int) SubscriptionPayment::paid()
                ->whereBetween('paid_at', [$m->copy()->startOfMonth(), $m->copy()->endOfMonth()])
                ->sum('amount');
        }

        // Reservas globales en los últimos 6 meses
        $bookingsCats   = [];
        $bookingsSeries = [];
        for ($i = 5; $i >= 0; $i--) {
            $m = $now->copy()->subMonths($i);
            $bookingsCats[]   = $m->isoFormat('MMM');
            $bookingsSeries[] = Booking::whereBetween('created_at', [$m->copy()->startOfMonth(), $m->copy()->endOfMonth()])->count();
        }

        // Distribución de planes
        $planDistribution = Plan::active()
            ->withCount('companies')
            ->ordered()
            ->get(['id', 'name', 'price_monthly']);

        $latestCompanies = Company::with('plan')->latest()->limit(5)->get();
        $expiringSubs = Subscription::with('company:id,name,slug')
            ->expiringSoon(14)
            ->orderBy('current_period_end')
            ->limit(5)
            ->get();

        // Goal progress: meta arbitraria de 20 empresas activas para "premium" feel.
        $goal = max(20, $companiesNow + 5);
        $goalProgress = $goal > 0 ? min(100, round(($companiesNow / $goal) * 100)) : 0;

        return view('superadmin.dashboard', compact(
            'kpis', 'latestCompanies', 'expiringSubs',
            'sparkCompanies', 'sparkBookings', 'sparkRevenue',
            'revenueSeries', 'revenueCats',
            'bookingsCats', 'bookingsSeries',
            'planDistribution',
            'goal', 'goalProgress',
        ));
    }

    protected function trend(float $now, float $prev): float
    {
        if ($prev <= 0) {
            return $now > 0 ? 100 : 0;
        }
        return round((($now - $prev) / $prev) * 100, 1);
    }

    /** @return array<int> */
    protected function dailyCount($query, string $column, int $days): array
    {
        $end = now()->endOfDay();
        $start = $end->copy()->subDays($days - 1)->startOfDay();
        $rows = (clone $query)
            ->selectRaw("DATE($column) AS d, COUNT(*) AS c")
            ->whereBetween($column, [$start, $end])
            ->groupBy('d')
            ->pluck('c', 'd')
            ->all();
        $result = [];
        for ($i = $days - 1; $i >= 0; $i--) {
            $key = now()->subDays($i)->toDateString();
            $result[] = (int) ($rows[$key] ?? 0);
        }
        return $result;
    }

    protected function dailySum($query, string $column, string $sumColumn, int $days): array
    {
        $end = now()->endOfDay();
        $start = $end->copy()->subDays($days - 1)->startOfDay();
        $rows = (clone $query)
            ->selectRaw("DATE($column) AS d, SUM($sumColumn) AS s")
            ->whereBetween($column, [$start, $end])
            ->groupBy('d')
            ->pluck('s', 'd')
            ->all();
        $result = [];
        for ($i = $days - 1; $i >= 0; $i--) {
            $key = now()->subDays($i)->toDateString();
            $result[] = (float) ($rows[$key] ?? 0);
        }
        return $result;
    }
}
