<?php

namespace App\Filament\Pages\Reports;

use App\Filament\Resources\CustomerResource\Pages\ViewCustomer;
use App\Filament\Support\Perm;
use App\Models\Customers\Customer;
use App\Services\CurrentContext;
use Carbon\Carbon;
use Filament\Actions\Action;
use Filament\Support\Icons\Heroicon;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

/**
 * Ported from ReportController::customers(). Active customers only, with their
 * lifetime purchase/payment/due aggregates and last transaction date. The
 * report has no date window (lifetime figures), so `hasDateFilters()` is
 * false; search is native (searchable columns) and the row action jumps to
 * the Customer resource's view page when the user holds `isms_customers.view`.
 */
class CustomersReport extends ReportPage
{
    protected static string|\BackedEnum|null $navigationIcon = Heroicon::OutlinedUsers;

    protected static ?string $navigationLabel = 'Customer Report';

    protected static ?string $slug = 'reports/customers';

    protected static ?string $title = 'Customer Report';

    public static function moduleKey(): string
    {
        return 'reports_customers';
    }

    public function csvFilename(): string
    {
        return 'customers-report.csv';
    }

    public function hasDateFilters(): bool
    {
        return false;
    }

    public function columns(): array
    {
        return [
            'name' => 'Name',
            'phone' => 'Phone',
            'email' => 'Email',
            'credit_balance' => 'Credit Balance',
            'total_purchases' => 'Total Purchases',
            'total_paid' => 'Total Paid',
            'total_due' => 'Total Due',
            'last_transaction_date' => 'Last Transaction',
        ];
    }

    protected function reportQuery(): Builder
    {
        return Customer::query()
            ->where('is_active', true)
            ->withSum('invoices as total_purchases', 'net_total')
            ->withSum('invoices as total_due', 'balance')
            ->withSum('transactions as total_paid', 'amount')
            ->withMax('transactions as last_transaction_date', 'taken_on')
            ->with('creditBalance:customer_id,balance')
            ->orderBy('business_name');
    }

    public function table(Table $table): Table
    {
        return $this->baseTable($table)
            ->columns([
                TextColumn::make('business_name')->label('Name')->searchable()->sortable(),
                TextColumn::make('phone')->label('Phone')->searchable()->placeholder('—'),
                TextColumn::make('email')->label('Email')->searchable()->placeholder('—'),
                TextColumn::make('creditBalance.balance')->label('Credit Balance')
                    ->money(fn () => app(CurrentContext::class)->currencyCode())->placeholder('—'),
                TextColumn::make('total_purchases')->label('Total Purchases')
                    ->money(fn () => app(CurrentContext::class)->currencyCode())->placeholder('—')->sortable(),
                TextColumn::make('total_paid')->label('Total Paid')
                    ->money(fn () => app(CurrentContext::class)->currencyCode())->placeholder('—')->sortable(),
                TextColumn::make('total_due')->label('Total Due')
                    ->money(fn () => app(CurrentContext::class)->currencyCode())->placeholder('—')->sortable(),
                TextColumn::make('last_transaction_date')->label('Last Transaction')->date()->placeholder('—'),
            ])
            ->recordActions([
                Action::make('view')
                    ->label('View')
                    ->icon('heroicon-m-eye')
                    ->color('gray')
                    ->url(fn (Customer $record): string => ViewCustomer::getUrl(['record' => $record]))
                    ->visible(fn (): bool => Perm::can('isms_customers', 'view')),
            ]);
    }

    protected function exportRow(Model $record): array
    {
        $customer = $record;

        return [
            'name' => $customer->business_name,
            'phone' => $customer->phone ?? '—',
            'email' => $customer->email ?? '—',
            'credit_balance' => (float) ($customer->creditBalance?->balance ?? 0),
            'total_purchases' => (float) ($customer->total_purchases ?? 0),
            'total_paid' => (float) ($customer->total_paid ?? 0),
            'total_due' => (float) ($customer->total_due ?? 0),
            'last_transaction_date' => $customer->last_transaction_date
                ? Carbon::parse($customer->last_transaction_date)->toDateString()
                : null,
        ];
    }

    public function summary(): array
    {
        return [];
    }

    protected function receiptLine(Model $record): array
    {
        $customer = $record;

        return [
            'label' => $customer->business_name.($customer->phone ? ' · '.$customer->phone : ''),
            'value' => $this->formatAmount($customer->total_due ?? 0).' due',
        ];
    }

    protected function receiptTotals(): array
    {
        $query = $this->filteredQuery();

        return [
            ['label' => 'Total purchases', 'value' => $this->formatAmount($query->clone()->sum('total_purchases'))],
            ['label' => 'Total paid', 'value' => $this->formatAmount($query->clone()->sum('total_paid'))],
            ['label' => 'Total due', 'value' => $this->formatAmount($query->clone()->sum('total_due'))],
        ];
    }
}
