<?php

namespace App\Http\Controllers\Tenant;

use App\Http\Controllers\Controller;
use App\Models\Booking;
use App\Models\Customer;
use App\Models\Employee;
use App\Models\Service;
use App\Support\Tenant;
use Illuminate\View\View;

class DashboardController extends Controller
{
    public function index(): View
    {
        $company = Tenant::current();
        $now     = now();
        $startMonth     = $now->copy()->startOfMonth();
        $prevMonthStart = $now->copy()->subMonth()->startOfMonth();
        $prevMonthEnd   = $now->copy()->subMonth()->endOfMonth();

        $bookingsMonth = Booking::whereBetween('booking_date', [$startMonth, $now])->count();
        $bookingsPrev  = Booking::whereBetween('booking_date', [$prevMonthStart, $prevMonthEnd])->count();
        $bookingsTrend = $this->trend($bookingsMonth, $bookingsPrev);

        $revenueMonth = (float) Booking::whereBetween('booking_date', [$startMonth, $now])
                                    ->where('status', 'completed')->sum('total_amount');
        $revenuePrev  = (float) Booking::whereBetween('booking_date', [$prevMonthStart, $prevMonthEnd])
                                    ->where('status', 'completed')->sum('total_amount');
        $revenueTrend = $this->trend($revenueMonth, $revenuePrev);

        $kpis = [
            'bookings_today'   => Booking::whereDate('booking_date', $now->toDateString())->count(),
            'bookings_pending' => Booking::pending()->count(),
            'bookings_month'   => $bookingsMonth,
            'bookings_trend'   => $bookingsTrend,
            'revenue_month'    => $revenueMonth,
            'revenue_trend'    => $revenueTrend,
            'customers_total'  => Customer::count(),
            'services_active'  => Service::active()->count(),
            'employees_active' => Employee::active()->count(),
        ];

        // Reservas últimas 14 días
        $sparkBookings = $this->dailyCount(Booking::query(), 'booking_date', 14);
        $sparkRevenue  = $this->dailySum(Booking::where('status', 'completed'), 'booking_date', 'total_amount', 14);

        // Reservas por día últimas 4 semanas para chart principal
        $cats = [];
        $bookingsSeries = [];
        $completedSeries = [];
        for ($i = 27; $i >= 0; $i--) {
            $d = $now->copy()->subDays($i);
            $cats[] = $d->isoFormat('DD MMM');
            $bookingsSeries[]  = Booking::whereDate('booking_date', $d->toDateString())->count();
            $completedSeries[] = Booking::whereDate('booking_date', $d->toDateString())->where('status', 'completed')->count();
        }

        // Top 5 servicios más reservados (mes en curso)
        $topServices = Booking::query()
            ->whereBetween('booking_date', [$startMonth, $now])
            ->selectRaw('service_id, COUNT(*) as total')
            ->groupBy('service_id')
            ->orderByDesc('total')
            ->limit(5)
            ->with('service:id,name,price')
            ->get();

        // Top empleados (mes en curso)
        $topEmployees = Booking::query()
            ->whereBetween('booking_date', [$startMonth, $now])
            ->whereNotNull('employee_id')
            ->selectRaw('employee_id, COUNT(*) as total')
            ->groupBy('employee_id')
            ->orderByDesc('total')
            ->limit(5)
            ->with('employee:id,first_name,last_name,color,position')
            ->get();

        // Distribución por estado del mes
        $statusBreakdown = Booking::whereBetween('booking_date', [$startMonth, $now])
            ->selectRaw('status, COUNT(*) as total')
            ->groupBy('status')
            ->pluck('total', 'status')
            ->all();

        $upcoming = Booking::with(['customer', 'service', 'employee'])
            ->active()
            ->where('scheduled_at', '>=', $now)
            ->orderBy('scheduled_at')
            ->limit(6)
            ->get();

        return view('tenant.dashboard', compact(
            'company', 'kpis', 'upcoming',
            'sparkBookings', 'sparkRevenue',
            'cats', 'bookingsSeries', 'completedSeries',
            'topServices', 'topEmployees', 'statusBreakdown',
        ));
    }

    protected function trend(float $now, float $prev): float
    {
        if ($prev <= 0) return $now > 0 ? 100 : 0;
        return round((($now - $prev) / $prev) * 100, 1);
    }

    protected function dailyCount($query, string $column, int $days): array
    {
        $end = now()->endOfDay();
        $start = $end->copy()->subDays($days - 1)->startOfDay();
        $rows = (clone $query)
            ->selectRaw("DATE($column) AS d, COUNT(*) AS c")
            ->whereBetween($column, [$start, $end])
            ->groupBy('d')
            ->pluck('c', 'd')
            ->all();
        $result = [];
        for ($i = $days - 1; $i >= 0; $i--) {
            $key = now()->subDays($i)->toDateString();
            $result[] = (int) ($rows[$key] ?? 0);
        }
        return $result;
    }

    protected function dailySum($query, string $column, string $sumColumn, int $days): array
    {
        $end = now()->endOfDay();
        $start = $end->copy()->subDays($days - 1)->startOfDay();
        $rows = (clone $query)
            ->selectRaw("DATE($column) AS d, SUM($sumColumn) AS s")
            ->whereBetween($column, [$start, $end])
            ->groupBy('d')
            ->pluck('s', 'd')
            ->all();
        $result = [];
        for ($i = $days - 1; $i >= 0; $i--) {
            $key = now()->subDays($i)->toDateString();
            $result[] = (float) ($rows[$key] ?? 0);
        }
        return $result;
    }
}
