<?php

namespace App\Filament\Exports;

use App\Models\Order;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
use Illuminate\Database\Eloquent\Builder;

class OrderExporter extends Exporter
{
    protected static ?string $model = Order::class;

    public static function modifyQuery(Builder $query): Builder
    {
        return $query->with(['centers', 'finance', 'association', 'state', 'city', 'user', 'activities' => function ($query) {
            $query->whereIn('event', ['approved', 'rejected', 'send_back'])
                ->latest()
                ->limit(1);
        }]);
    }

    public static function getColumns(): array
    {
        return [
            ExportColumn::make('id')
                ->label(__('order.id')),
            ExportColumn::make('association.name')
                ->label(__('order.association')),
            ExportColumn::make('association.license_number')
                ->label(__('order.association_license_number')),
            ExportColumn::make('type')
                ->label(__('order.order_type'))
                ->formatStateUsing(fn (?string $state): string => $state ? __(Order::getAllOrderTypes()[$state] ?? $state) : ''),
            ExportColumn::make('status')
                ->label(__('order.status'))
                ->formatStateUsing(fn (?string $state): string => $state ? __(Order::getOrderStatuses()[$state] ?? $state) : ''),
            ExportColumn::make('lat')
                ->label(__('order.lat')),
            ExportColumn::make('lng')
                ->label(__('order.lng')),
            ExportColumn::make('calculated_families_count')
                ->label(__('order.calculated_families_count'))
                ->state(function (Order $record): int {
                    return $record->calculateTotalFamilies();
                }),
            ExportColumn::make('number_of_families')
                ->label(__('order.manual_families_entry')),
            ExportColumn::make('centers')
                ->label(__('order.centers'))
                ->state(function (Order $record): ?string {
                    $centers = $record->centers;

                    return $centers->isNotEmpty() ? $centers->pluck('name')->join(', ') : null;
                }),
            ExportColumn::make('finance.approved_price')
                ->label(__('order.finance_approved_price'))
                ->state(function (Order $record): ?string {
                    return $record->finance && $record->finance->approved_price !== null
                        ? number_format($record->finance->approved_price, 2)
                        : null;
                }),
            ExportColumn::make('finance.count')
                ->label(__('order.finance_count'))
                ->state(function (Order $record): ?int {
                    return $record->finance?->count;
                }),
            ExportColumn::make('finance.capacity')
                ->label(__('order.finance_capacity'))
                ->state(function (Order $record): ?string {
                    return $record->finance?->capacity;
                }),
            ExportColumn::make('finance.execution_duration')
                ->label(__('order.finance_execution_duration'))
                ->state(function (Order $record): ?int {
                    return $record->finance?->execution_duration;
                }),
            ExportColumn::make('finance.company_name')
                ->label(__('order.finance_company_name'))
                ->state(function (Order $record): ?string {
                    return $record->finance?->company_name;
                }),
            ExportColumn::make('finance.offer_price')
                ->label(__('order.finance_offer_price'))
                ->state(function (Order $record): ?string {
                    return $record->finance && $record->finance->offer_price !== null
                        ? number_format($record->finance->offer_price, 2)
                        : null;
                }),
            ExportColumn::make('finance.additional_fees')
                ->label(__('order.finance_additional_fees'))
                ->state(function (Order $record): ?string {
                    return $record->finance && $record->finance->additional_fees !== null
                        ? number_format($record->finance->additional_fees, 2)
                        : null;
                }),
            ExportColumn::make('finance.operation_cost_percentage')
                ->label(__('order.finance_operation_cost_percentage'))
                ->state(function (Order $record): ?string {
                    return $record->finance && $record->finance->operation_cost_percentage !== null
                        ? number_format($record->finance->operation_cost_percentage, 2).'%'
                        : null;
                }),
            ExportColumn::make('finance.expected_operation_cost')
                ->label(__('order.finance_expected_operation_cost'))
                ->state(function (Order $record): ?string {
                    return $record->finance && $record->finance->expected_operation_cost !== null
                        ? number_format($record->finance->expected_operation_cost, 2)
                        : null;
                }),
            ExportColumn::make('water_source')
                ->label(__('order.water_source'))
                ->formatStateUsing(fn (?string $state): string => $state ? __(Order::getWaterSources()[$state] ?? $state) : ''),
            ExportColumn::make('water_distance')
                ->label(__('order.water_distance')),
            ExportColumn::make('order_justifications')
                ->label(__('order.order_justifications')),
            ExportColumn::make('order_description')
                ->label(__('order.order_description')),
            ExportColumn::make('created_by')
                ->label(__('order.created_by'))
                ->state(function (Order $record): ?string {
                    return $record->user?->name;
                }),
            ExportColumn::make('created_at')
                ->label(__('order.created_at')),
            ExportColumn::make('updated_at')
                ->label(__('order.updated_at')),
            ExportColumn::make('state.name')
                ->label(__('order.state')),
            ExportColumn::make('city.name')
                ->label(__('order.city')),
            ExportColumn::make('latest_activity_event')
                ->label(__('order.latest_activity_event'))
                ->state(function (Order $record): ?string {
                    $activity = $record->activities->first();
                    if (! $activity) {
                        return null;
                    }

                    $eventTranslations = [
                        'approved' => __('order.activity_approved'),
                        'rejected' => __('order.activity_rejected'),
                        'send_back' => __('order.activity_send_back'),
                    ];

                    return $eventTranslations[$activity->event] ?? $activity->event;
                }),
            ExportColumn::make('latest_activity_user')
                ->label(__('order.latest_activity_user'))
                ->state(function (Order $record): ?string {
                    $activity = $record->activities->first();

                    return $activity?->causer?->name;
                }),
            ExportColumn::make('latest_activity_date')
                ->label(__('order.latest_activity_date'))
                ->state(function (Order $record): ?string {
                    $activity = $record->activities->first();

                    return $activity?->created_at?->format('Y-m-d H:i:s');
                }),
        ];
    }

    public static function getCompletedNotificationBody(Export $export): string
    {
        $successfulRows = $export->successful_rows;
        $rowWord = $successfulRows === 1 ? __('order.row') : __('order.rows');

        $body = __('order.export_completed', [
            'count' => number_format($successfulRows),
            'rows' => $rowWord,
        ]);

        if ($failedRowsCount = $export->getFailedRowsCount()) {
            $failedRowWord = $failedRowsCount === 1 ? __('order.row') : __('order.rows');
            $body .= __('order.export_failed_rows', [
                'count' => number_format($failedRowsCount),
                'rows' => $failedRowWord,
            ]);
        }

        return $body;
    }
}
