<?php

namespace App\Filament\Pages;

use App\Exports\ReportArrayExport;
use App\Support\AccountingReportPdfBuilder;
use Filament\Pages\Page;
use App\Services\AccountingReportService;
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Schemas\Schema;
use Maatwebsite\Excel\Facades\Excel;

class ProfitLossReport extends Page implements HasForms
{
    use InteractsWithForms, HasPageShield;

    protected static \BackedEnum|string|null $navigationIcon = 'heroicon-o-chart-bar';

    protected string $view = 'filament.pages.profit-loss-report';

    protected static string|\UnitEnum|null $navigationGroup = 'الحسابات الختامية';

    protected static ?int $navigationSort = 2;

    public ?string $startDate = null;
    public ?string $endDate = null;
    public array $reportData = [];

    protected AccountingReportService $reportService;

    public function boot(AccountingReportService $reportService): void
    {
        $this->reportService = $reportService;
    }

    public function mount(): void
    {
        $this->startDate = now()->startOfYear()->toDateString();
        $this->endDate = now()->toDateString();

        $this->form->fill([
            'start_date' => $this->startDate,
            'end_date' => $this->endDate,
        ]);

        $this->loadReport();
    }

    public static function getNavigationLabel(): string
    {
        return __('filament/admin/profit_loss_report.navigation_label');
    }

    public function getTitle(): string
    {
        return __('filament/admin/profit_loss_report.title');
    }

    protected function getHeaderActions(): array
    {
        return [
            \Filament\Actions\Action::make('export_pdf')
                ->label(__('filament/admin/profit_loss_report.export_pdf'))
                ->icon('heroicon-o-document-arrow-down')
                ->action('exportPdf'),
            
            \Filament\Actions\Action::make('export_excel')
                ->label(__('filament/admin/profit_loss_report.export_excel'))
                ->icon('heroicon-o-table-cells')
                ->action('exportExcel'),
        ];
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                DatePicker::make('start_date')
                    ->label(__('filament/admin/profit_loss_report.from_date'))
                    ->default(now()->startOfYear())
                    ->required()
                    ->live()
                    ->afterStateUpdated(function ($state) {
                        $this->startDate = $state;
                        $this->loadReport();
                    }),

                DatePicker::make('end_date')
                    ->label(__('filament/admin/profit_loss_report.to_date'))
                    ->default(now())
                    ->required()
                    ->live()
                    ->afterStateUpdated(function ($state) {
                        $this->endDate = $state;
                        $this->loadReport();
                    }),
            ])
            ->columns(2);
    }

    public function loadReport(): void
    {
        $this->reportData = $this->reportService->profitAndLoss($this->startDate, $this->endDate);
    }

    public function exportPdf(): \Symfony\Component\HttpFoundation\StreamedResponse
    {
        $rows = [];

        foreach (($this->reportData['revenues']['items'] ?? []) as $revenue) {
            $rows[] = [__('filament/admin/profit_loss_report.revenue'), $revenue['code'] ?? '', $revenue['name'] ?? '', number_format((float) ($revenue['balance'] ?? 0), 2)];
        }

        foreach (($this->reportData['expenses']['items'] ?? []) as $expense) {
            $rows[] = [__('filament/admin/profit_loss_report.expense'), $expense['code'] ?? '', $expense['name'] ?? '', number_format((float) ($expense['balance'] ?? 0), 2)];
        }

        return AccountingReportPdfBuilder::download(
            title: __('filament/admin/profit_loss_report.title'),
            subtitle: __('filament/admin/profit_loss_report.subtitle', ['start' => $this->startDate, 'end' => $this->endDate]),
            headings: [__('filament/admin/profit_loss_report.type'), __('filament/admin/profit_loss_report.code'), __('filament/admin/profit_loss_report.account_name'), __('filament/admin/profit_loss_report.value')],
            rows: $rows,
            summary: [
                __('filament/admin/profit_loss_report.total_revenues') => number_format((float) ($this->reportData['revenues']['total'] ?? 0), 2),
                __('filament/admin/profit_loss_report.total_expenses') => number_format((float) ($this->reportData['expenses']['total'] ?? 0), 2),
                __('filament/admin/profit_loss_report.net_income') => number_format((float) ($this->reportData['net_income'] ?? 0), 2),
            ],
            fileName: sprintf('profit-loss-%s-to-%s.pdf', $this->startDate, $this->endDate),
        );
    }

    public function exportExcel(): \Symfony\Component\HttpFoundation\StreamedResponse
    {
        $rows = [];

        foreach (($this->reportData['revenues']['items'] ?? []) as $revenue) {
            $rows[] = [__('filament/admin/profit_loss_report.revenue'), $revenue['code'] ?? '', $revenue['name'] ?? '', (float) ($revenue['balance'] ?? 0)];
        }

        foreach (($this->reportData['expenses']['items'] ?? []) as $expense) {
            $rows[] = [__('filament/admin/profit_loss_report.expense'), $expense['code'] ?? '', $expense['name'] ?? '', (float) ($expense['balance'] ?? 0)];
        }

        $rows[] = [__('filament/admin/profit_loss_report.total_revenues'), '', '', (float) ($this->reportData['revenues']['total'] ?? 0)];
        $rows[] = [__('filament/admin/profit_loss_report.total_expenses'), '', '', (float) ($this->reportData['expenses']['total'] ?? 0)];
        $rows[] = [__('filament/admin/profit_loss_report.net_income'), '', '', (float) ($this->reportData['net_income'] ?? 0)];

        $filename = sprintf('profit-loss-%s-to-%s.xlsx', $this->startDate, $this->endDate);

        return response()->streamDownload(function () use ($rows) {
            echo Excel::raw(
                new ReportArrayExport(
                    headings: [__('filament/admin/profit_loss_report.type'), __('filament/admin/profit_loss_report.code'), __('filament/admin/profit_loss_report.account_name'), __('filament/admin/profit_loss_report.value')],
                    rows: $rows,
                ),
                \Maatwebsite\Excel\Excel::XLSX,
            );
        }, $filename);
    }

    protected function getViewData(): array
    {
        return [
            'reportData' => $this->reportData,
        ];
    }
}
