<?php

namespace App\Filament\Resources;

use App\Enums\InvoiceStatus;
use App\Filament\Resources\InvoiceReportResource\Pages;
use App\Models\Order;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Grouping\Group;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;

class InvoiceReportResource extends Resource
{
    protected static ?string $model = Order::class;

    protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';

    protected static ?string $navigationGroup = 'Reports';

    protected static ?string $navigationLabel = 'Invoice Reports';

    protected static ?int $navigationSort = 2;

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                //
            ]);
    }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                Tables\Columns\TextColumn::make('invoice.date')
                    ->label('Date')
                    ->date('Y-m-d'),

                Tables\Columns\TextColumn::make('invoice.internal_id')
                    ->color('primary')
                    ->fontFamily('mono'),

                Tables\Columns\TextColumn::make('customer_po')
                    ->color('code')
                    ->weight('bold')
                    ->extraHeaderAttributes(['class' => 'w-full']),

                Tables\Columns\TextColumn::make('total_service_price')
                    ->label('Subtotal')
                    ->alignRight()
                    ->money(),

                Tables\Columns\TextColumn::make('pst')
                    ->label('PST')
                    ->alignRight()
                    ->getStateUsing(fn (Order $record) => $record->invoice->pst ? $record->total_service_price * 0.07 : 0.00)
                    ->formatStateUsing(function ($state) {
                        return $state == 0.00 ? '-' : '$'.$state;
                    }),

                Tables\Columns\TextColumn::make('gst')
                    ->label('GST')
                    ->getStateUsing(fn (Order $record) => $record->total_service_price * 0.05)
                    ->alignRight()
                    ->money(),

                Tables\Columns\TextColumn::make('invoice.total')
                    ->label('Total')
                    ->getStateUsing(function (Order $record) {
                        $total = $record->total_service_price * 1.05;

                        if ($record->invoice->pst) {
                            $total += $record->total_service_price * 0.07;
                        }

                        return $total;
                    })
                    ->alignRight()
                    ->money(),

                Tables\Columns\TextColumn::make('invoice.status')
                    ->badge(InvoiceStatus::class),
            ])

            ->filters([
                Tables\Filters\SelectFilter::make('customer')
                    ->relationship('customer', 'company_name')
                    ->preload()
                    ->searchable()
                    ->placeholder('Select a customer...')
                    ->selectablePlaceholder(false)
                    ->query(function (array $data, Builder $query): Builder {
                        return $query->where('orders.customer_id', $data['value'] ?? '-1');
                    }),

                Tables\Filters\Filter::make('date_from')
                    ->form([DatePicker::make('date_from')])
                    ->query(function (Builder $query, array $data): Builder {
                        return $query->when($data['date_from'], function (Builder $query, $date) {
                            return $query->whereHas('invoice', fn ($query) => $query->whereDate('date', '>=', $date));
                        });
                    }),

                Tables\Filters\Filter::make('date_until')
                    ->form([DatePicker::make('date_until')])
                    ->query(function (Builder $query, array $data): Builder {
                        return $query->when($data['date_until'], function (Builder $query, $date) {
                            return $query->whereHas('invoice', fn ($query) => $query->whereDate('date', '<=', $date));
                        });
                    }),

                Tables\Filters\SelectFilter::make('invoice_status')
                    ->options(InvoiceStatus::class)
                    ->query(function (Builder $query, array $data): Builder {
                        return $query->when($data['value'], fn (Builder $query, $value) => $query->whereHas('invoice', fn (Builder $query) => $query->where('status', $value)));
                    }),

            ], layout: Tables\Enums\FiltersLayout::AboveContent)
            ->hiddenFilterIndicators()

            ->actions([])
            ->defaultGroup(
                Group::make('date')
                    ->getKeyFromRecordUsing(fn (Order $record): string => $record->invoice->date->format('Y-m-0'))
                    ->getTitleFromRecordUsing(fn (Order $record): string => $record->invoice->date->format('F Y'))
                    ->orderQueryUsing(function (Builder $query) {

                        return $query->join('invoices', 'orders.invoice_id', '=', 'invoices.id')
                            ->orderBy('invoices.date', 'desc');
                    })
                    ->titlePrefixedWithLabel(false),
            );
    }

    public static function getEloquentQuery(): \Illuminate\Database\Eloquent\Builder
    {
        return Order::query()
            ->has('invoice');
    }

    public static function getRelations(): array
    {
        return [
            //
        ];
    }

    public static function getPages(): array
    {
        return [
            'index' => Pages\ListInvoiceReports::route('/'),
        ];
    }
}
