<?php

namespace App\Filament\Pages\Reports;

use App\Filament\Support\StatusLookup;
use App\Models\Lookups\Status;
use App\Models\Returns\ReturnDoc;
use App\Services\CurrentContext;
use Filament\Actions\Action;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\View;
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::purchases().
 *
 * Named "Returns Report" because that is what it actually reports on: despite
 * the controller method and route being called `purchases`, the query is over
 * `returns`, the CSV is written as `returns-report.csv`, and MenuDefinition
 * labels the `reports_purchases` module "Returns Report". The module key is
 * kept as `reports_purchases` so existing permission grants keep working.
 *
 * The row action opens a read-only modal with the return's header and line
 * items (the "View on Returns report" requirement).
 */
class ReturnsReport extends ReportPage
{
    protected static string|\BackedEnum|null $navigationIcon = Heroicon::OutlinedArrowUturnLeft;

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

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

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

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

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

    public function columns(): array
    {
        return [
            'date' => 'Date',
            'reference' => 'Reference',
            'customer' => 'Customer',
            'branch' => 'Branch',
            'items' => 'Items',
            'total' => 'Total',
            'status' => 'Status',
        ];
    }

    protected function reportQuery(): Builder
    {
        return ReturnDoc::query()
            ->when($this->branchFilter(), fn ($q, $branchId) => $q->where('branch_id', $branchId))
            ->with(['customer:id,business_name', 'branch:id,name', 'status:id,code,name'])
            ->withCount('items')
            ->orderByDesc('created_at');
    }

    public function table(Table $table): Table
    {
        return $this->baseTable($table)
            ->columns([
                TextColumn::make('created_at')->label('Date')->date()->sortable(),
                TextColumn::make('return_number')->label('Reference')->searchable()->sortable(),
                TextColumn::make('customer.business_name')->label('Customer')->placeholder('—')->searchable(),
                TextColumn::make('branch.name')->label('Branch')->placeholder('—'),
                TextColumn::make('items_count')->label('Items')->sortable(),
                TextColumn::make('total')->label('Total')->money(fn () => app(CurrentContext::class)->currencyCode())->sortable(),
                TextColumn::make('status.code')->label('Status')
                    ->badge()
                    ->color(fn (string $state): ?string => StatusLookup::colorOf(Status::CTX_RETURN, $state))
                    ->formatStateUsing(fn (string $state): string => StatusLookup::nameOf(Status::CTX_RETURN, $state)),
            ])
            ->recordActions([$this->returnViewAction()]);
    }

    protected function returnViewAction(): Action
    {
        return Action::make('view')
            ->label('View')
            ->icon('heroicon-m-eye')
            ->color('gray')
            ->schema([
                Section::make()->columns(4)->schema([
                    TextEntry::make('return_number')->label('Reference'),
                    TextEntry::make('created_at')->label('Date')->dateTime(),
                    TextEntry::make('customer.business_name')->label('Customer')->placeholder('—'),
                    TextEntry::make('branch.name')->label('Branch')->placeholder('—'),
                    TextEntry::make('status.name')->label('Status')->badge()
                        ->color(fn (ReturnDoc $record): ?string => StatusLookup::colorOf(Status::CTX_RETURN, (string) ($record->status?->code ?? ''))),
                    TextEntry::make('refundMethod.name')->label('Refund method')->placeholder('—'),
                    TextEntry::make('refund_amount')->label('Refunded')
                        ->money(fn (): string => app(CurrentContext::class)->currencyCode())->placeholder('—'),
                    TextEntry::make('total')->label('Total')
                        ->money(fn (): string => app(CurrentContext::class)->currencyCode()),
                    TextEntry::make('note')->label('Note')->placeholder('—')->columnSpanFull(),
                ]),

                Section::make('Items')->schema([
                    View::make('filament.pages.reports.partials.return-items')
                        ->viewData(fn (ReturnDoc $record): array => [
                            'items' => $record->items()->with(['product:id,name,sku', 'reason:id,name', 'unit:id,code,name'])->get(),
                        ]),
                ]),
            ]);
    }

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

        return [
            'date' => $return->created_at->toDateString(),
            'reference' => $return->return_number,
            'customer' => $return->customer?->business_name ?? '—',
            'branch' => $return->branch?->name ?? '—',
            'items' => $return->items_count,
            'total' => (float) $return->total,
            'status' => $return->status?->code ?? '',
        ];
    }

    public function summary(): array
    {
        $rows = $this->rows();

        return [
            'Total returns' => 'Rs. '.number_format(array_sum(array_column($rows, 'total')), 2),
            'Count' => (string) count($rows),
            'Total items' => (string) array_sum(array_column($rows, 'items')),
        ];
    }

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

        return [
            'label' => $return->created_at->format('d/m/y').' '.$return->return_number.' — '.($return->customer?->business_name ?? '—'),
            'value' => $this->formatAmount($return->total),
        ];
    }

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

        return [
            ['label' => 'Total returns', 'value' => $this->formatAmount($query->clone()->sum('total'))],
            ['label' => 'Returns', 'value' => (string) $query->clone()->count()],
        ];
    }
}
