<?php

namespace App\Filament\Widgets;

use App\Models\Subscription;
use Filament\Widgets\ChartWidget;
use Illuminate\Support\Facades\DB;

class RevenueMetrics extends ChartWidget
{
    protected static ?int $sort = 1;

    protected int|string|array $columnSpan = 'full';

    public function getHeading(): string
    {
        return 'Revenue Trends';
    }

    protected function getData(): array
    {
        $monthlyRevenue = $this->getMonthlyRevenueTrend();
        $mrrByProvider = $this->getMRRByProvider();

        return [
            'datasets' => [
                [
                    'label' => 'Monthly Revenue',
                    'data' => array_values($monthlyRevenue),
                    'borderColor' => 'rgba(34, 197, 94, 1)',
                    'backgroundColor' => 'rgba(34, 197, 94, 0.1)',
                    'fill' => true,
                    'tension' => 0.4,
                ],
                [
                    'label' => 'MRR by Provider',
                    'data' => array_values($mrrByProvider),
                    'borderColor' => 'rgba(59, 130, 246, 1)',
                    'backgroundColor' => 'rgba(59, 130, 246, 0.1)',
                    'fill' => true,
                    'tension' => 0.4,
                ],
            ],
            'labels' => array_keys($monthlyRevenue),
        ];
    }

    protected function getType(): string
    {
        return 'line';
    }

    protected function getOptions(): array
    {
        return [
            'responsive' => true,
            'interaction' => [
                'intersect' => false,
                'mode' => 'index',
            ],
            'plugins' => [
                'legend' => [
                    'position' => 'top',
                ],
                'tooltip' => [
                    'callbacks' => [
                        'label' => 'function(context) {
                            let label = context.dataset.label || "";
                            if (label) {
                                label += ": ";
                            }
                            if (context.parsed.y !== null) {
                                label += "$" + context.parsed.y.toFixed(2);
                            }
                            return label;
                        }',
                    ],
                ],
            ],
            'scales' => [
                'y' => [
                    'beginAtZero' => true,
                    'ticks' => [
                        'callback' => 'function(value) {
                            return "$" + value;
                        }',
                    ],
                ],
            ],
        ];
    }

    private function getMonthlyRevenueTrend(): array
    {
        $dateFormat = $this->getDateFormatExpression();

        return Subscription::query()
            ->select(
                DB::raw("{$dateFormat} as month"),
                DB::raw('SUM(plans.price) as revenue')
            )
            ->join('plans', 'subscriptions.plan_id', '=', 'plans.id')
            ->where('subscriptions.status', 'active')
            ->where('subscriptions.created_at', '>=', now()->subMonths(12))
            ->groupBy('month')
            ->orderBy('month')
            ->pluck('revenue', 'month')
            ->toArray();
    }

    private function getDateFormatExpression(): string
    {
        $connection = DB::connection()->getDriverName();

        return match ($connection) {
            'sqlite' => "strftime('%Y-%m', subscriptions.created_at)",
            'mysql', 'mariadb' => "DATE_FORMAT(subscriptions.created_at, '%Y-%m')",
            'pgsql' => "TO_CHAR(subscriptions.created_at, 'YYYY-MM')",
            'sqlsrv' => "FORMAT(subscriptions.created_at, 'yyyy-MM')",
            default => "DATE_FORMAT(subscriptions.created_at, '%Y-%m')", // fallback to MySQL format
        };
    }

    private function getMRRByProvider(): array
    {
        return Subscription::query()
            ->select(
                'provider',
                DB::raw('SUM(plans.price) as mrr')
            )
            ->join('plans', 'subscriptions.plan_id', '=', 'plans.id')
            ->where('subscriptions.status', 'active')
            ->groupBy('provider')
            ->orderBy('mrr', 'desc')
            ->pluck('mrr', 'provider')
            ->toArray();
    }
}
