<?php

namespace App\Filament\Widgets;

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

class TrialPerformance extends ChartWidget
{
    protected static ?int $sort = 4;

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

    public function getHeading(): string
    {
        return 'Trial Performance';
    }

    protected function getData(): array
    {
        $trialConversion = $this->getTrialConversionRates();
        $trialExtensions = $this->getTrialExtensionsTrend();

        return [
            'datasets' => [
                [
                    'label' => 'Trial Conversion Rate (%)',
                    'data' => array_values($trialConversion),
                    'borderColor' => 'rgba(168, 85, 247, 1)',
                    'backgroundColor' => 'rgba(168, 85, 247, 0.1)',
                    'fill' => true,
                    'tension' => 0.4,
                ],
                [
                    'label' => 'Trial Extensions',
                    'data' => array_values($trialExtensions),
                    'borderColor' => 'rgba(251, 146, 60, 1)',
                    'backgroundColor' => 'rgba(251, 146, 60, 0.1)',
                    'fill' => true,
                    'tension' => 0.4,
                ],
            ],
            'labels' => array_keys($trialConversion),
        ];
    }

    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) {
                                if (label.includes("Rate")) {
                                    label += context.parsed.y.toFixed(1) + "%";
                                } else {
                                    label += context.parsed.y;
                                }
                            }
                            return label;
                        }',
                    ],
                ],
            ],
            'scales' => [
                'y' => [
                    'beginAtZero' => true,
                    'ticks' => [
                        'callback' => 'function(value, index, values) {
                            if (index === 0 || index === values.length - 1) {
                                return value + (this.chart.data.datasets[0].label.includes("Rate") ? "%" : "");
                            }
                            return "";
                        }',
                    ],
                ],
            ],
        ];
    }

    private function getTrialConversionRates(): array
    {
        $conversionData = [];

        for ($i = 5; $i >= 0; $i--) {
            $month = now()->subMonths($i);
            $monthStart = $month->copy()->startOfMonth();
            $monthEnd = $month->copy()->endOfMonth();

            // Trials that ended during this month
            $endedTrials = Subscription::query()
                ->where('status', 'trialing')
                ->whereBetween('trial_ends_at', [$monthStart, $monthEnd])
                ->get();

            $totalTrials = $endedTrials->count();
            $convertedTrials = $endedTrials->filter(function ($trial) use ($monthEnd) {
                // Check if trial converted to paid subscription
                return Subscription::query()
                    ->where('user_id', $trial->user_id)
                    ->where('status', 'active')
                    ->where('created_at', '>', $trial->trial_ends_at)
                    ->where('created_at', '<=', $monthEnd)
                    ->exists();
            })->count();

            $conversionRate = $totalTrials > 0 ? ($convertedTrials / $totalTrials) * 100 : 0;

            $conversionData[$month->format('M Y')] = round($conversionRate, 2);
        }

        return $conversionData;
    }

    private function getTrialExtensionsTrend(): array
    {
        return TrialExtension::query()
            ->select(
                DB::raw("strftime('%Y-%m', trial_extensions.granted_at) as month"),
                DB::raw('COUNT(*) as extensions'),
                DB::raw('SUM(extension_days) as total_days')
            )
            ->where('trial_extensions.granted_at', '>=', now()->subMonths(6))
            ->groupBy('month')
            ->orderBy('month')
            ->get()
            ->mapWithKeys(function ($item) {
                $date = \Carbon\Carbon::createFromFormat('Y-m', $item->month);

                return [$date->format('M Y') => $item->extensions];
            })
            ->toArray();
    }

    private function getAverageTrialLength(): float
    {
        return Subscription::query()
            ->where('status', 'trialing')
            ->orWhere('status', 'active')
            ->whereNotNull('trial_ends_at')
            ->selectRaw('AVG(DATEDIFF(trial_ends_at, created_at)) as avg_trial_days')
            ->value('avg_trial_days') ?? 0;
    }

    private function getMostCommonExtensionReasons(): array
    {
        return TrialExtension::query()
            ->select('reason', DB::raw('COUNT(*) as count'))
            ->whereNotNull('reason')
            ->groupBy('reason')
            ->orderBy('count', 'desc')
            ->limit(5)
            ->pluck('count', 'reason')
            ->toArray();
    }
}
