<?php

namespace App\Services;

use App\Enums\InvoiceStatus;
use App\Enums\LineStatus;
use App\Enums\PaymentStatus;
use App\Models\CashDrawer;
use App\Models\Customer;
use App\Models\Invoice;
use App\Models\Line;
use App\Models\Payment;
use Illuminate\Http\Request;

class DashboardService
{
    public function stats(): array
    {
        $today = now()->toDateString();
        $monthStart = now()->startOfMonth()->toDateString();
        $monthEnd = now()->endOfMonth()->toDateString();

        $lineCounts = Line::query()
            ->selectRaw('status, count(*) as aggregate')
            ->groupBy('status')
            ->pluck('aggregate', 'status');

        $drawer = CashDrawer::currentOpen();

        return [
            'total_lines' => Line::query()->count(),
            'available_lines' => (int) ($lineCounts[LineStatus::Available->value] ?? 0),
            'sold_lines' => (int) ($lineCounts[LineStatus::Sold->value] ?? 0) + (int) ($lineCounts[LineStatus::Active->value] ?? 0),
            'active_lines' => (int) ($lineCounts[LineStatus::Active->value] ?? 0),
            'suspended_lines' => (int) ($lineCounts[LineStatus::Suspended->value] ?? 0),
            'cancelled_lines' => (int) ($lineCounts[LineStatus::Cancelled->value] ?? 0),
            'total_customers' => Customer::query()->count(),
            'today_sales' => (string) Invoice::query()->where('invoice_type', 'sale')->whereDate('date', $today)->whereNotIn('status', ['cancelled', 'void'])->sum('total'),
            'today_collections' => (string) Payment::query()->whereDate('date', $today)->where('status', 'completed')->sum('amount'),
            'today_expenses' => (string) ($drawer?->transactions()->where('type', 'expense')->whereDate('date', $today)->sum('amount') ?? 0),
            'current_cash' => (string) ($drawer->expected_balance ?? '0.00'),
            'outstanding' => (string) Invoice::query()->whereIn('status', [InvoiceStatus::Active->value, InvoiceStatus::PartiallyPaid->value])->sum('remaining'),
            'overdue_bills' => Line::query()->whereNotNull('customer_id')->whereIn('status', ['sold', 'active', 'suspended'])->count(),
            'month_revenue' => (string) Invoice::query()->whereBetween('date', [$monthStart, $monthEnd])->whereNotIn('status', ['cancelled', 'void'])->sum('total'),
            'month_collections' => (string) Payment::query()->whereBetween('date', [$monthStart, $monthEnd])->where('status', 'completed')->sum('amount'),
            'version' => app_version(),
        ];
    }

    public function charts(): array
    {
        $labels = [];
        $sales = [];
        $collections = [];

        for ($i = 5; $i >= 0; $i--) {
            $month = now()->subMonths($i);
            $labels[] = $month->locale(app()->getLocale())->translatedFormat('M Y');
            $start = $month->copy()->startOfMonth()->toDateString();
            $end = $month->copy()->endOfMonth()->toDateString();
            $sales[] = (float) Invoice::query()->whereBetween('date', [$start, $end])->whereNotIn('status', ['cancelled', 'void'])->sum('total');
            $collections[] = (float) Payment::query()->whereBetween('date', [$start, $end])->where('status', 'completed')->sum('amount');
        }

        return compact('labels', 'sales', 'collections');
    }

    public function widgets(Request $request): array
    {
        $date = $request->date('date')?->toDateString() ?? now()->toDateString();
        $limit = dashboard_limit();

        $payments = Payment::query()
            ->with(['customer', 'line'])
            ->whereDate('date', $date)
            ->where('status', PaymentStatus::Completed->value)
            ->latest('id')
            ->paginate($limit, ['*'], 'payments_page')
            ->withQueryString();

        $availableLines = Line::query()
            ->with('telecomCompany')
            ->where('status', LineStatus::Available->value)
            ->latest('id')
            ->paginate($limit, ['*'], 'lines_page')
            ->withQueryString();

        return [
            'date' => $date,
            'limit' => $limit,
            'recentPayments' => $payments,
            'availableLines' => $availableLines,
        ];
    }
}
