<?php

namespace App\Filament\Pages;

use App\Imports\InvoicePendingReasonImport;
use App\Models\InvoiceDataValidation;
use App\Models\InvoiceOutValidation;
use App\Models\Plant;
use Filament\Pages\Page;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Form;
use Filament\Facades\Filament;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
use Illuminate\Support\Facades\Auth;
use Maatwebsite\Excel\Facades\Excel;
use Storage;

class InvoicePendingReason extends Page
{
    use HasFiltersForm;
    protected static ?string $navigationIcon = 'heroicon-o-document-text';

    protected static string $view = 'filament.pages.invoice-pending-reason';

    protected static ?string $navigationGroup = 'Manufacturing SD';

    public ?string $file = null;

    public array $importErrors = [];

    public array $invoicePending = [];


    public function mount(): void
    {
       $this->filtersForm->fill([
           'plant_id' => null,
           'document_number' => null,
           'remark' => null,
       ]);
    }

    public function filtersForm(Form $form): Form
    {
        return $form
            ->statePath('filters')
            ->schema([
                Select::make('plant_id')
                    ->label('Plant')
                    ->reactive()
                    ->required()
                    ->columnSpan(1)
                    ->options(function (callable $get) {
                        $userHas = Filament::auth()->user()->plant_id;
                        return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
                    })
                    ->afterStateUpdated(function ($state, $set, callable $get,$livewire)  {
                        $plantId = $get('plant_id');

                        if($plantId){
                            $this->dispatch('loadData' ,$plantId);
                        }
                        else{
                            $this->dispatch('emptyData');
                        }

                        $set('document_number', null);
                        $set('customer_trade_name', null);
                        $set('location', null);
                    })
                    ->hint(fn ($get) => $get('pqPlantError') ? $get('pqPlantError') : null)
                    ->hintColor('danger'),

                Select::make('document_number')
                    ->label('Document Number')
                    ->required()
                    ->reactive()
                    ->columnSpan(1)
                    ->options(function (callable $get) {
                        $plantId = $get('plant_id');
                        if (empty($plantId)) {
                            return [];
                        }

                        $distributions = InvoiceDataValidation::whereNotNull('distribution_channel_desc')
                            ->distinct()
                            ->pluck('distribution_channel_desc')
                            ->filter(fn ($v) => trim($v) !== '')
                            ->values()
                            ->toArray();

                        $distributions[] = '';

                        $pendingInvoices = collect();

                        foreach ($distributions as $distribution) {

                            $invoices = InvoiceDataValidation::where('plant_id', $plantId)
                                ->where('distribution_channel_desc', $distribution)
                                ->select('id', 'document_number')
                                ->get()
                                ->unique('document_number')
                                ->filter(fn ($inv) =>
                                    ! empty($inv->document_number) &&
                                    ! str_contains($inv->document_number, '-')
                                );

                            if (trim($distribution) == '') {
                                $invoices = $invoices->filter(fn ($inv) =>
                                    str_starts_with($inv->document_number, '7')
                                );
                            }

                            if ($invoices->isEmpty()) {
                                continue;
                            }

                            $invoiceNumbers = $invoices->pluck('document_number')
                                ->map(fn ($n) => preg_replace('/\s+/', '', strtoupper($n)))
                                ->toArray();

                            $wentOut = InvoiceOutValidation::whereIn('qr_code', $invoiceNumbers)
                                ->distinct()
                                ->pluck('qr_code')
                                ->map(fn ($n) => preg_replace('/\s+/', '', strtoupper($n)))
                                ->toArray();

                            $pending = $invoices->filter(function ($inv) use ($wentOut) {
                                $doc = preg_replace('/\s+/', '', strtoupper($inv->document_number));
                                return ! in_array($doc, $wentOut, true);
                            });

                            $pendingInvoices = $pendingInvoices->merge($pending);
                        }

                        return $pendingInvoices
                            ->unique('document_number')
                            ->pluck('document_number', 'document_number')
                            ->toArray();
                    })
                    ->afterStateUpdated(function ($state, callable $set, callable $get) {
                        $plantId = $get('plant_id');
                        if (empty($plantId)) {
                            return [];
                        }
                        $documentNumber = $get('document_number');

                        $customers = InvoiceDataValidation::where('plant_id', $plantId)
                            ->where('document_number', $documentNumber)
                            ->value('customer_trade_name');

                        $location = InvoiceDataValidation::where('plant_id', $plantId)
                            ->where('document_number', $documentNumber)
                            ->value('location');

                        $set('customer_trade_name', $customers);
                        $set('location', $location);
                    })
                    ->extraAttributes(fn ($get) => [
                        'class' => $get('pqBlockError') ? 'border-red-500' : '',
                    ])
                    ->hint(fn ($get) => $get('pqBlockError') ? $get('pqBlockError') : null)
                    ->hintColor('danger'),
                TextInput::make('customer_trade_name')
                    ->label('Customer Trade Name')
                    ->required()
                    ->readOnly()
                    ->reactive()
                    ->columnSpan(1),
                TextInput::make('location')
                    ->label('Location')
                    ->required()
                    ->readOnly()
                    ->reactive()
                    ->columnSpan(1),
                TextInput::make('remark')
                    ->label('Remark')
                    ->reactive()
                    ->maxLength(40)
                    ->helperText('Max 40 characters allowed.')
                    ->extraAttributes([
                        'wire:keydown.enter.prevent' => 'addRemark($event.target.value)',
                    ])
                    ->autofocus()
                    ->required(),
                FileUpload::make('file')
                    ->label('Upload Excel File')
                    ->required()
                    ->disk('local')
                    ->multiple(false)
                    ->directory('invoice-pending')
                    ->dehydrated(false)
                    //->preserveFilenames()
                    //->storeFiles()
                    //storeFileNamesIn('original_name')
                   // ->visibility('private')
                    ->acceptedFileTypes([
                        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
                        'application/vnd.ms-excel',
                        'text/csv',
                    ])
                    ->rules(['mimes:xlsx,xls,csv'])
                    ->afterStateUpdated(function ($state, callable $set) {
                        if ($state instanceof \Livewire\Features\SupportFileUploads\TemporaryUploadedFile) {
                            $set('file', $state->store('invoice-pending'));
                        }
                    }),
                ])
        ->columns(3);
    }

    public function addRemark(){
        $plantId        = $this->filters['plant_id'] ?? null;
        $documentNumber = $this->filters['document_number'] ?? null;
        $remark         = $this->filters['remark'] ?? null;

        if (! $plantId) {
            Notification::make()
                ->title('Plant')
                ->body("please select plant first..!")
                ->danger()
                ->send();
            return;
        }
        if (! $documentNumber) {
            Notification::make()
                ->title('Document Number')
                ->body("please select document number..!")
                ->danger()
                ->send();
            return;
        }
        if ($remark == '') {
            Notification::make()
                ->title('Remark')
                ->body("Remark can't be empty..!")
                ->danger()
                ->send();
            return;
        }

        InvoiceDataValidation::where('plant_id', $plantId)
        ->where('document_number', $documentNumber)
        ->update([
            'remark'     => $remark,
            'updated_at' => now(),
        ]);

        $this->filtersForm->fill([
            'plant_id'        => $plantId,
            'document_number' => $documentNumber,
            'remark'          => null,
        ]);

        Notification::make()
            ->title('Remark updated successfully')
            ->success()
            ->send();
    }

    // public function importPendingReason()
    // {

    //     $file = $this->filters['file'] ?? null;

    //     $absolutePath = Storage::disk('local')->path($file);

    //     Excel::import(new InvoicePendingReasonImport, $absolutePath);

    //     $this->reset('filters.file');

    //     Notification::make()
    //         ->title('File processed and database updated successfully')
    //         ->success()
    //         ->send();
    // }

    public function importPendingReason()
    {
        $file = $this->filters['file'] ?? null;

        $plantId = $this->filters['plant_id'] ?? null;

        if (empty($file)) {
            Notification::make()
                ->title('Please upload a file')
                ->danger()
                ->send();
            return;
        }

        // if (
        //     empty($fileFilter) ||
        //     !is_array($fileFilter) ||
        //     empty($fileFilter[0])
        // ) {
        //     Notification::make()
        //         ->title('Please upload a file')
        //         ->danger()
        //         ->send();

        //     return;
        // }


        // $filePath = $fileFilter[0];

        // if (!is_string($filePath)) {
        //     Notification::make()
        //         ->title('Invalid file upload')
        //         ->danger()
        //         ->send();

        //     return;
        // }

        $absolutePath = Storage::disk('local')->path($file);

        $import = new InvoicePendingReasonImport();

        try {

            Excel::import(
                $import,
                $absolutePath
            );

            if(!empty($import->plantCodeEmpty)) {

                Notification::make()
                    ->title('Import failed')
                    ->body("Plant code can't be empty")
                    ->danger()
                    ->send();
                $this->filtersForm->fill([
                    'file' => null,
                    'plant_id' => $plantId,
                ]);
                return;
            }
            else if(!empty($import->docNoEmpty)) {

                Notification::make()
                    ->title('Import failed')
                    ->body("Document number can't be empty")
                    ->danger()
                    ->send();
                $this->filtersForm->fill([
                    'file' => null,
                    'plant_id' => $plantId,
                ]);
                return;
            }
            else if (! empty($import->duplicateExcelDocs)) {

                $duplicates = collect($import->duplicateExcelDocs)
                    ->map(function ($rows, $key) {
                        [$plant, $doc] = explode('|', $key);
                        return "{$plant}-{$doc}";
                    })
                    ->implode(', ');

                Notification::make()
                    ->title('Import failed')
                    ->body("Duplicate Document Numbers found in Excel: {$duplicates}")
                    ->danger()
                    ->send();
                $this->filtersForm->fill([
                    'file' => null,
                    'plant_id' => $plantId,
                ]);
                return;
            }
            else if(!empty($import->missingPlantCodes)) {
                $codes = implode(', ', array_keys($import->missingPlantCodes));
                Notification::make()
                    ->title('Import failed')
                    ->body("Plant codes not found: {$codes}")
                    ->danger()
                    ->send();
                $this->filtersForm->fill([
                    'file' => null,
                    'plant_id' => $plantId,
                ]);
                return;
            }
            else if(!empty($import->missingDocNo)) {
                $docNo = implode(', ', array_keys($import->missingDocNo));
                Notification::make()
                    ->title('Import failed')
                    ->body("Document numbers not found: {$docNo}")
                    ->danger()
                    ->send();
                $this->filtersForm->fill([
                    'file' => null,
                    'plant_id' => $plantId,
                ]);
                return;
            }

            foreach ($import->validRows as $row) {
                InvoiceDataValidation::where('plant_id', $row['plant_id'])
                    ->where('document_number', $row['document_number'])
                    ->update([
                        'remark' => $row['remark'],
                        'updated_at' => now(),
                    ]);
            }

            Notification::make()
                ->title('Import successful')
                ->body('All records updated successfully.')
                ->success()
                ->send();

            $this->dispatch('loadData' ,$plantId);

            $this->filtersForm->fill([
                'file' => null,
                'plant_id' => $plantId,
            ]);

        } catch (\Throwable $e) {

            Notification::make()
                ->title('Import error')
                ->body($e->getMessage())
                ->danger()
                ->send();
        }
    }

    public function exportPendingReason()
    {
        $plantId = $this->filters['plant_id'] ?? null;

        if (! $plantId) {
            Notification::make()
                ->title('Plant')
                ->body("please select plant to export data..!")
                ->danger()
                ->send();
            return;
        }

        $this->dispatch('loadData1' ,$plantId);

    }

    public static function canAccess(): bool
    {
        return Auth::check() && Auth::user()->can('view invoice pending reason');
    }
}
