<?php

declare(strict_types=1);

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Invoice;
use App\Models\PaymentTransaction;
use App\Models\Plan;
use App\Models\Service;
use App\Models\User;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;
use Inertia\Response;
use Laravel\Cashier\Subscription;

class DashboardController extends Controller
{
    public function index(): Response
    {
        $stats = Cache::remember('admin.dashboard.stats', 300, function () {
            $totalCustomers = User::role('customer')->count();

            // MRR: sum of plan prices for active subscriptions
            $mrr = (float) Subscription::query()
                ->where('stripe_status', 'active')
                ->whereNotNull('plan_id')
                ->join('plans', 'subscriptions.plan_id', '=', 'plans.id')
                ->sum('plans.price');

            // Total revenue: sum of paid invoice totals
            $totalRevenue = (float) Invoice::query()
                ->where('status', 'paid')
                ->sum('total');

            $activeServices = Service::query()
                ->where('status', 'active')
                ->count();

            // Pending invoices
            $pendingInvoicesCount = Invoice::query()
                ->where('status', 'pending')
                ->count();

            $pendingInvoicesAmount = (float) Invoice::query()
                ->where('status', 'pending')
                ->sum('total');

            // Overdue invoices
            $overdueCount = Invoice::query()
                ->where('status', 'overdue')
                ->count();

            $overdueAmount = (float) Invoice::query()
                ->where('status', 'overdue')
                ->sum('total');

            // Recent invoices with user info
            $recentInvoices = Invoice::query()
                ->with('user:id,name,email')
                ->latest()
                ->limit(10)
                ->get(['id', 'user_id', 'number', 'total', 'status', 'gateway', 'created_at']);

            // Recent subscriptions with user and plan
            $recentSubscriptions = Subscription::query()
                ->select([
                    'subscriptions.id',
                    'subscriptions.user_id',
                    'subscriptions.plan_id',
                    'subscriptions.type',
                    'subscriptions.stripe_status',
                    'subscriptions.gateway',
                    'subscriptions.created_at',
                ])
                ->leftJoin('plans', 'subscriptions.plan_id', '=', 'plans.id')
                ->addSelect([
                    'plans.name as plan_name',
                    'plans.price as plan_price',
                    'plans.billing_cycle as plan_billing_cycle',
                ])
                ->leftJoin('users', 'subscriptions.user_id', '=', 'users.id')
                ->addSelect([
                    'users.name as user_name',
                    'users.email as user_email',
                ])
                ->orderByDesc('subscriptions.created_at')
                ->limit(10)
                ->get();

            // Popular plans: ordered by active subscription count
            $popularPlans = Plan::query()
                ->withCount(['services as active_services_count' => function ($query): void {
                    $query->where('status', 'active');
                }])
                ->where('status', 'active')
                ->orderByDesc('active_services_count')
                ->limit(8)
                ->get(['id', 'name', 'service_type', 'price', 'billing_cycle']);

            // Revenue by service type from plans linked through invoices
            $revenueByServiceType = Invoice::query()
                ->where('invoices.status', 'paid')
                ->join('subscriptions', 'invoices.subscription_id', '=', 'subscriptions.id')
                ->join('plans', 'subscriptions.plan_id', '=', 'plans.id')
                ->select('plans.service_type', DB::raw('SUM(invoices.total) as revenue'), DB::raw('COUNT(invoices.id) as invoice_count'))
                ->groupBy('plans.service_type')
                ->orderByDesc('revenue')
                ->get();

            // New customers this month
            $newCustomersThisMonth = User::role('customer')
                ->where('created_at', '>=', now()->startOfMonth())
                ->count();

            // Revenue this month
            $revenueThisMonth = (float) Invoice::query()
                ->where('status', 'paid')
                ->where('paid_at', '>=', now()->startOfMonth())
                ->sum('total');

            // ARR (Annual Recurring Revenue)
            $arr = $mrr * 12;

            // Monthly Revenue Trend (last 12 months)
            $revenueByMonth = PaymentTransaction::query()
                ->where('status', 'completed')
                ->where('created_at', '>=', now()->subMonths(12))
                ->selectRaw("DATE_FORMAT(created_at, '%Y-%m') as month, SUM(amount) as total")
                ->groupBy('month')
                ->orderBy('month')
                ->get()
                ->map(fn ($row) => ['month' => $row->month, 'total' => (float) $row->total]);

            // Customer Growth (last 12 months - new signups per month)
            $customerGrowth = User::role('customer')
                ->where('created_at', '>=', now()->subMonths(12))
                ->selectRaw("DATE_FORMAT(created_at, '%Y-%m') as month, COUNT(*) as count")
                ->groupBy('month')
                ->orderBy('month')
                ->get()
                ->map(fn ($row) => ['month' => $row->month, 'count' => (int) $row->count]);

            // Churn Rate (subscriptions cancelled vs total in last 6 months)
            $churnData = [];
            for ($i = 5; $i >= 0; $i--) {
                $monthStart = now()->subMonths($i)->startOfMonth();
                $monthEnd = now()->subMonths($i)->endOfMonth();

                $totalAtStart = Subscription::query()
                    ->where('created_at', '<', $monthStart)
                    ->where(function ($query) use ($monthStart): void {
                        $query->whereNull('cancelled_at')
                            ->orWhere('cancelled_at', '>', $monthStart);
                    })
                    ->count();

                $cancelled = Subscription::query()
                    ->whereBetween('cancelled_at', [$monthStart, $monthEnd])
                    ->count();

                $churnData[] = [
                    'month' => $monthStart->format('Y-m'),
                    'rate' => $totalAtStart > 0 ? round(($cancelled / $totalAtStart) * 100, 1) : 0,
                    'cancelled' => $cancelled,
                ];
            }

            // Overdue Invoices (detailed list)
            $overdueInvoices = Invoice::query()
                ->where('status', 'overdue')
                ->with('user:id,name,email')
                ->latest('due_date')
                ->take(10)
                ->get(['id', 'user_id', 'number', 'total', 'due_date', 'status']);

            return compact(
                'totalCustomers',
                'mrr',
                'totalRevenue',
                'activeServices',
                'pendingInvoicesCount',
                'pendingInvoicesAmount',
                'overdueCount',
                'overdueAmount',
                'recentInvoices',
                'recentSubscriptions',
                'popularPlans',
                'revenueByServiceType',
                'newCustomersThisMonth',
                'revenueThisMonth',
                'arr',
                'revenueByMonth',
                'customerGrowth',
                'churnData',
                'overdueInvoices',
            );
        });

        return Inertia::render('Admin/Dashboard', $stats);
    }
}
