<?php

namespace App\Livewire\Admin\Laporan;

use App\Enums\OrderStatus;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\User;
use Illuminate\Support\Carbon;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;

#[Layout('layouts.admin')]
#[Title('Laporan')]
class Index extends Component
{
    use WithPagination;

    // ── Filter Periode ───────────────────────────────────────────────────
    // #[Url] agar filter tersinkron ke query string URL — dipakai juga
    // oleh link Export CSV/Excel agar data yang diunduh konsisten dengan layar.
    #[Url(as: 'period')]
    public string $period     = 'today'; // today | week | month | custom

    #[Url(as: 'dateFrom')]
    public string $dateFrom   = '';

    #[Url(as: 'dateTo')]
    public string $dateTo     = '';

    public int $perPage = 25;

    public function mount(): void
    {
        $this->dateFrom = now()->startOfMonth()->format('Y-m-d');
        $this->dateTo   = now()->format('Y-m-d');
    }

    public function updatingPeriod(): void  { $this->resetPage(); }
    public function updatingDateFrom(): void { $this->resetPage(); }
    public function updatingDateTo(): void   { $this->resetPage(); }
    public function updatingPerPage(): void  { $this->resetPage(); }

    public function setPeriod(string $period): void
    {
        $this->period = $period;
        $this->resetPage();
    }

    /**
     * Hitung rentang tanggal [start, end] berdasarkan periode yang dipilih.
     * Dipakai konsisten oleh statistik, tabel, dan export.
     */
    public function getDateRange(): array
    {
        return match ($this->period) {
            'week'   => [now()->startOfWeek(), now()->endOfWeek()],
            'month'  => [now()->startOfMonth(), now()->endOfMonth()],
            'custom' => [
                Carbon::parse($this->dateFrom ?: now())->startOfDay(),
                Carbon::parse($this->dateTo ?: now())->endOfDay(),
            ],
            default  => [now()->startOfDay(), now()->endOfDay()], // 'today'
        };
    }

    /**
     * Query dasar order untuk laporan: status Selesai, dalam rentang tanggal.
     * Dipakai sama persis oleh statistik, tabel, dan export — agar angka selalu konsisten.
     */
    private function baseOrdersQuery()
    {
        [$from, $to] = $this->getDateRange();

        return Order::where('status', OrderStatus::Completed->value)
            ->whereBetween('created_at', [$from, $to]);
    }

    public function render()
    {
        [$from, $to] = $this->getDateRange();

        // ── Statistik ────────────────────────────────────────────────────
        // total_penjualan dan total_pesanan digabung jadi satu query agregat
        // karena sama-sama dari tabel orders dengan kondisi yang identik.
        $orderAggregate = (clone $this->baseOrdersQuery())
            ->selectRaw('COUNT(*) as total_pesanan, COALESCE(SUM(grand_total), 0) as total_penjualan')
            ->first();

        $totalProdukTerjual = OrderItem::whereHas('order', function ($q) use ($from, $to) {
            $q->where('status', OrderStatus::Completed->value)
              ->whereBetween('created_at', [$from, $to]);
        })->sum('quantity');

        $totalCustomer = (clone $this->baseOrdersQuery())
            ->whereNotNull('user_id')
            ->distinct('user_id')
            ->count('user_id');

        $stats = [
            'total_penjualan'      => (float) $orderAggregate->total_penjualan,
            'total_pesanan'        => (int) $orderAggregate->total_pesanan,
            'total_produk_terjual' => (int) $totalProdukTerjual,
            'total_customer'       => $totalCustomer,
        ];

        // ── Tabel ────────────────────────────────────────────────────────
        $orders = (clone $this->baseOrdersQuery())
            ->latest()
            ->paginate($this->perPage);

        return view('livewire.admin.laporan.index', compact('stats', 'orders', 'from', 'to'));
    }
}
