<?php

namespace App\Http\Controllers\SuperAdmin;

use App\Http\Controllers\Controller;
use App\Models\Organization;
use App\Models\User;
use App\Models\Sale;
use App\Models\Product;
use App\Models\Subscription;
use App\Models\SystemLog;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class DashboardController extends Controller
{
    public function overview(): JsonResponse
    {
        $now   = Carbon::now();
        $month = $now->copy()->startOfMonth();
        $prev  = $now->copy()->subMonth()->startOfMonth();
        $today = $now->copy()->startOfDay();

        // ── Organizations ──────────────────────────────────────────────────
        $totalOrgs    = Organization::count();
        $activeOrgs   = Organization::where('is_active', true)->count();
        $newOrgsMonth = Organization::where('created_at', '>=', $month)->count();
        $newOrgsPrev  = Organization::whereBetween('created_at', [$prev, $month])->count();

        // ── Subscriptions ──────────────────────────────────────────────────
        $activeSubs   = Subscription::where('status', 'active')->count();
        $trialSubs    = Subscription::where('status', 'trial')->count();
        $subsPrev     = Subscription::where('status', 'active')
            ->where('created_at', '<', $month)->count();

        // MRR: sum monthly-equivalent amounts for active subscriptions
        $mrr = Subscription::where('status', 'active')
            ->selectRaw("SUM(CASE WHEN billing_cycle='yearly' THEN amount/12 ELSE amount END) as mrr")
            ->value('mrr') ?? 0;
        $mrrPrev = Subscription::where('status', 'active')
            ->where('created_at', '<', $month)
            ->selectRaw("SUM(CASE WHEN billing_cycle='yearly' THEN amount/12 ELSE amount END) as mrr")
            ->value('mrr') ?? 0;

        // ── Sales / Revenue ────────────────────────────────────────────────
        $totalSalesValue = Sale::sum('total');
        $totalSalesCount = Sale::count();
        $revenueMonth    = Sale::where('created_at', '>=', $month)->sum('total');
        $revenuePrev     = Sale::whereBetween('created_at', [$prev, $month])->sum('total');
        $salesMonth      = Sale::where('created_at', '>=', $month)->count();

        // ── Users ──────────────────────────────────────────────────────────
        $totalUsers      = User::withoutGlobalScopes()->count();
        $activeUsersToday = SystemLog::whereDate('created_at', $today)
            ->whereNotNull('user_id')
            ->distinct('user_id')
            ->count('user_id');

        // ── Products ───────────────────────────────────────────────────────
        $totalProducts = Product::withoutGlobalScopes()->count();

        // ── Errors ─────────────────────────────────────────────────────────
        $errorLogs = SystemLog::withoutGlobalScopes()
            ->where('created_at', '>=', $now->copy()->subDay())
            ->where('description', 'LIKE', '%error%')
            ->count();

        return response()->json([
            'total_businesses'    => $totalOrgs,
            'active_subscriptions'=> $activeSubs,
            'trial_accounts'      => $trialSubs,
            'mrr'                 => round($mrr, 2),
            'mrr_growth'          => $this->growthPercent($mrrPrev, $mrr),
            'total_transactions'  => $totalSalesCount,
            'active_users_today'  => $activeUsersToday,
            'total_products'      => $totalProducts,
            'total_sales_value'   => round($totalSalesValue, 2),

            'organizations' => [
                'total'      => $totalOrgs,
                'active'     => $activeOrgs,
                'inactive'   => $totalOrgs - $activeOrgs,
                'this_month' => $newOrgsMonth,
                'growth'     => $this->growthPercent($newOrgsPrev, $newOrgsMonth),
            ],
            'revenue' => [
                'this_month' => round($revenueMonth, 2),
                'prev_month' => round($revenuePrev, 2),
                'growth'     => $this->growthPercent($revenuePrev, $revenueMonth),
                'this_month_sales' => $salesMonth,
            ],
            'errors_24h'  => $errorLogs,
            'server_time' => $now->toIso8601String(),
        ]);
    }

    public function chartsData(): JsonResponse
    {
        $now = Carbon::now();

        // ── 1. Tenant growth (12 months) ───────────────────────────────────
        $tenantGrowth = collect(range(11, 0))->map(function ($i) use ($now) {
            $date = $now->copy()->subMonths($i)->startOfMonth();
            return [
                'month' => $date->format('M Y'),
                'count' => Organization::whereYear('created_at', $date->year)
                    ->whereMonth('created_at', $date->month)
                    ->count(),
            ];
        });

        // ── 2. Revenue growth (12 months) ─────────────────────────────────
        $revenueGrowth = collect(range(11, 0))->map(function ($i) use ($now) {
            $date = $now->copy()->subMonths($i)->startOfMonth();
            return [
                'month'   => $date->format('M Y'),
                'revenue' => round(Sale::whereYear('created_at', $date->year)
                    ->whereMonth('created_at', $date->month)
                    ->sum('total'), 2),
            ];
        });

        // ── 3. Sales volume (12 months count) ─────────────────────────────
        $salesVolume = collect(range(11, 0))->map(function ($i) use ($now) {
            $date = $now->copy()->subMonths($i)->startOfMonth();
            return [
                'month' => $date->format('M Y'),
                'sales' => Sale::whereYear('created_at', $date->year)
                    ->whereMonth('created_at', $date->month)
                    ->count(),
            ];
        });

        // ── 4. Active vs Inactive tenants ─────────────────────────────────
        $totalOrgs    = Organization::count();
        $activeOrgs   = Organization::where('is_active', true)->count();
        $tenantStatus = [
            ['label' => 'Active',   'value' => $activeOrgs],
            ['label' => 'Inactive', 'value' => max(0, $totalOrgs - $activeOrgs)],
        ];

        // ── 5. Plan distribution ───────────────────────────────────────────
        $planDist = Subscription::where('status', 'active')
            ->select('plan', DB::raw('count(*) as count'))
            ->groupBy('plan')
            ->orderByDesc('count')
            ->get()
            ->map(fn($r) => ['label' => ucfirst($r->plan), 'value' => $r->count]);

        // Add "No Plan" bucket for orgs without subscriptions
        $orgsWithSub   = Subscription::where('status', 'active')->distinct('organization_id')->count();
        $orgsWithoutSub = max(0, $totalOrgs - $orgsWithSub);
        if ($orgsWithoutSub > 0) {
            $planDist->push(['label' => 'No Plan', 'value' => $orgsWithoutSub]);
        }

        return response()->json([
            'tenant_growth'  => $tenantGrowth,
            'revenue_growth' => $revenueGrowth,
            'sales_volume'   => $salesVolume,
            'tenant_status'  => $tenantStatus,
            'plan_dist'      => $planDist,
        ]);
    }

    public function activityFeed(): JsonResponse
    {
        $feed = [];

        // New tenant registrations (last 7)
        Organization::orderByDesc('created_at')->take(7)
            ->get(['id', 'name', 'email', 'created_at'])
            ->each(function ($org) use (&$feed) {
                $feed[] = [
                    'type'    => 'registration',
                    'icon'    => 'building',
                    'color'   => 'violet',
                    'title'   => "New business registered",
                    'detail'  => $org->name,
                    'sub'     => $org->email ?? '',
                    'time'    => $org->created_at->toIso8601String(),
                ];
            });

        // Recent subscription changes (last 7)
        Subscription::with('organization:id,name')
            ->orderByDesc('updated_at')->take(7)
            ->get()
            ->each(function ($sub) use (&$feed) {
                $statusMeta = [
                    'active'    => ['color' => 'emerald', 'label' => 'activated'],
                    'trial'     => ['color' => 'blue',    'label' => 'started trial'],
                    'cancelled' => ['color' => 'red',     'label' => 'cancelled'],
                    'expired'   => ['color' => 'amber',   'label' => 'expired'],
                ];
                $meta = $statusMeta[$sub->status] ?? ['color' => 'gray', 'label' => $sub->status];
                $feed[] = [
                    'type'   => 'subscription',
                    'icon'   => 'credit-card',
                    'color'  => $meta['color'],
                    'title'  => "Subscription " . $meta['label'],
                    'detail' => $sub->organization?->name ?? 'Unknown Org',
                    'sub'    => ucfirst($sub->plan) . ' plan · ' . ucfirst($sub->billing_cycle ?? ''),
                    'time'   => $sub->updated_at->toIso8601String(),
                ];
            });

        // High-value transactions (top 7 by total)
        Sale::orderByDesc('total')->take(7)
            ->with('organization:id,name')
            ->get(['id', 'total', 'created_at', 'organization_id'])
            ->each(function ($sale) use (&$feed) {
                $feed[] = [
                    'type'   => 'transaction',
                    'icon'   => 'cash',
                    'color'  => 'amber',
                    'title'  => "High-value transaction",
                    'detail' => number_format($sale->total, 2),
                    'sub'    => $sale->organization?->name ?? 'Unknown Org',
                    'time'   => $sale->created_at->toIso8601String(),
                ];
            });

        // System alerts (recent error-level logs, last 7)
        SystemLog::withoutGlobalScopes()
            ->where('description', 'LIKE', '%error%')
            ->orWhere('description', 'LIKE', '%failed%')
            ->orderByDesc('created_at')->take(7)
            ->get(['id', 'action', 'description', 'created_at'])
            ->each(function ($log) use (&$feed) {
                $feed[] = [
                    'type'   => 'alert',
                    'icon'   => 'warning',
                    'color'  => 'red',
                    'title'  => "System alert",
                    'detail' => $log->action ?? 'System Event',
                    'sub'    => \Str::limit($log->description ?? '', 80),
                    'time'   => $log->created_at->toIso8601String(),
                ];
            });

        // Sort all items newest first, take 20
        usort($feed, fn($a, $b) => strcmp($b['time'], $a['time']));
        $feed = array_slice($feed, 0, 20);

        return response()->json(['data' => $feed]);
    }

    // Keep legacy endpoints for backward-compat
    public function registrationsChart(): JsonResponse
    {
        $months = collect(range(11, 0))->map(function ($i) {
            $date  = Carbon::now()->subMonths($i)->startOfMonth();
            return [
                'month' => $date->format('M Y'),
                'count' => Organization::whereYear('created_at', $date->year)
                    ->whereMonth('created_at', $date->month)->count(),
            ];
        });
        return response()->json(['data' => $months]);
    }

    public function revenueChart(): JsonResponse
    {
        $months = collect(range(11, 0))->map(function ($i) {
            $date = Carbon::now()->subMonths($i)->startOfMonth();
            return [
                'month'   => $date->format('M Y'),
                'revenue' => round(Sale::whereYear('created_at', $date->year)
                    ->whereMonth('created_at', $date->month)->sum('total'), 2),
            ];
        });
        return response()->json(['data' => $months]);
    }

    public function recentOrganizations(): JsonResponse
    {
        $orgs = Organization::withCount('users')
            ->orderByDesc('created_at')->take(10)->get();
        return response()->json(['data' => $orgs]);
    }

    private function growthPercent(float $prev, float $current): float
    {
        if ($prev == 0) return $current > 0 ? 100.0 : 0.0;
        return round((($current - $prev) / $prev) * 100, 1);
    }
}
