<?php

namespace App\Filament\Widgets;

use Illuminate\Support\Facades\Date;
use Illuminate\Support\Facades\DB;
use App\Models\Log;
use App\Models\Meta;
use App\Models\PremiumEmail;
use App\Models\Ticket;
use App\Models\User;
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;

class StatsOverview extends BaseWidget
{
    protected function getStats(): array
    {
        return [
            Stat::make('Total Users', $this->getUser())
                ->description($this->getComparisonDescription($this->getUser(), $this->getUser('yesterday')))
                ->descriptionIcon($this->getComparisonIcon($this->getUser(), $this->getUser('yesterday')))
                ->color($this->getComparisonColor($this->getUser(), $this->getUser('yesterday'))),
            Stat::make('Customers', $this->getCustomerCount())
                ->description($this->getComparisonDescription($this->getCustomerCount(), $this->getCustomerCount('yesterday')))
                ->descriptionIcon($this->getComparisonIcon($this->getCustomerCount(), $this->getCustomerCount('yesterday')))
                ->color($this->getComparisonColor($this->getCustomerCount(), $this->getCustomerCount('yesterday'))),
            Stat::make('Paid Users', $this->getUserPaid())
                ->description($this->getComparisonDescription($this->getUserPaid(), $this->getUserPaid()))
                ->descriptionIcon($this->getComparisonIcon($this->getUserPaid(), $this->getUserPaid()))
                ->color($this->getComparisonColor($this->getUserPaid(), $this->getUserPaid())),
            Stat::make('Logs Count', $this->getLogsCount())
                ->description($this->getComparisonDescription($this->getLogsCount(), $this->getLogsCount('yesterday')))
                ->descriptionIcon($this->getComparisonIcon($this->getLogsCount(), $this->getLogsCount('yesterday')))
                ->color($this->getComparisonColor($this->getLogsCount(), $this->getLogsCount('yesterday'))),
            Stat::make('Total Mailbox', $this->getTotalMailbox())
                ->description($this->getComparisonDescription($this->getTotalMailbox(), $this->getTotalMailbox()))
                ->descriptionIcon($this->getComparisonIcon($this->getTotalMailbox(), $this->getTotalMailbox()))
                ->color($this->getComparisonColor($this->getTotalMailbox(), $this->getTotalMailbox())),
            Stat::make('Emails Received', $this->getTotalEmailsReceived())
                ->description($this->getComparisonDescription($this->getTotalEmailsReceived(), $this->getTotalEmailsReceived()))
                ->descriptionIcon($this->getComparisonIcon($this->getTotalEmailsReceived(), $this->getTotalEmailsReceived()))
                ->color($this->getComparisonColor($this->getTotalEmailsReceived(), $this->getTotalEmailsReceived())),
            Stat::make('Emails Stored', $this->getStoreEmailsCount())
                ->description($this->getComparisonDescription($this->getStoreEmailsCount(), $this->getStoreEmailsCount('yesterday')))
                ->descriptionIcon($this->getComparisonIcon($this->getStoreEmailsCount(), $this->getStoreEmailsCount('yesterday')))
                ->color($this->getComparisonColor($this->getStoreEmailsCount(), $this->getStoreEmailsCount('yesterday'))),
            Stat::make('Open Tickets', $this->getOpenTicketsCount())
                ->description($this->getComparisonDescription($this->getOpenTicketsCount(), $this->getOpenTicketsCount()))
                ->descriptionIcon($this->getComparisonIcon($this->getOpenTicketsCount(), $this->getOpenTicketsCount()))
                ->color($this->getComparisonColor($this->getOpenTicketsCount(), $this->getOpenTicketsCount())),
            Stat::make('Closed Tickets', $this->getClosedTicketsCount())
                ->description($this->getComparisonDescription($this->getClosedTicketsCount(), $this->getClosedTicketsCount()))
                ->descriptionIcon($this->getComparisonIcon($this->getClosedTicketsCount(), $this->getClosedTicketsCount()))
                ->color($this->getComparisonColor($this->getClosedTicketsCount(), $this->getClosedTicketsCount())),
        ];
    }

    private function getComparisonDescription(int $today, int $yesterday): string
    {
        if ($today === $yesterday) {
            return 'No change';
        }

        $difference = $today - $yesterday;
        $percentage = $yesterday > 0 ? ($difference / $yesterday) * 100 : ($today > 0 ? 100 : 0);

        return sprintf(
            'Today: %d, Yesterday: %d (%s%.1f%%)',
            $today,
            $yesterday,
            $difference >= 0 ? '+' : '-',
            abs($percentage)
        );
    }

    private function getComparisonIcon(int $today, int $yesterday): ?string
    {
        if ($today === $yesterday) {
            return null;
        }

        return $today > $yesterday ? 'heroicon-o-arrow-up' : 'heroicon-o-arrow-down';
    }

    private function getComparisonColor(int $today, int $yesterday): string
    {
        if ($today === $yesterday) {
            return 'gray';
        }

        return $today > $yesterday ? 'success' : 'danger';
    }

    private function getUser(string $period = 'today'): int
    {
        if ($period === 'yesterday') {
            return User::query()->where('created_at', '<', Date::today('UTC')->startOfDay())->count();
        }

        return User::query()->count();
    }

    private function getUserPaid(): int
    {
        return DB::table('subscriptions')
            ->where('stripe_status', 'active')
            ->distinct('user_id')
            ->count('user_id');
    }

    private function getLogsCount(string $period = 'today'): int
    {
        if ($period === 'yesterday') {
            return Log::query()->where('created_at', '<', Date::today('UTC')->startOfDay())->count();
        }

        return Log::query()->count();
    }

    private function getTotalMailbox(): int
    {
        return Meta::query()->select('value')->where('key', 'email_ids_created')->first()->value ?? 0;
    }

    private function getTotalEmailsReceived(): int
    {
        return Meta::query()->select('value')->where('key', 'messages_received')->first()->value ?? 0;
    }

    private function getCustomerCount(string $period = 'today'): int
    {
        if ($period === 'yesterday') {
            return User::query()->whereNotNull('stripe_id')
                ->where('created_at', '<', Date::today('UTC')->startOfDay())
                ->count();
        }

        return User::query()->whereNotNull('stripe_id')->count();
    }

    private function getStoreEmailsCount(string $period = 'today'): int
    {
        if ($period === 'yesterday') {
            return PremiumEmail::query()->where('created_at', '<', Date::today('UTC')->startOfDay())->count();
        }

        return PremiumEmail::query()->count();
    }

    private function getOpenTicketsCount(): int
    {
        return Ticket::query()->whereIn('status', ['open', 'pending'])->count();
    }

    private function getClosedTicketsCount(): int
    {
        return Ticket::query()->whereIn('status', ['closed'])->count();
    }
}
