<?php

namespace App\Filament\Imports;

use App\Models\Item;
use App\Models\Plant;
use App\Models\StickerMaster;
use App\Models\StockDataMaster;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
use Filament\Facades\Filament;
use Str;

class StockDataMasterImporter extends Importer
{
    protected static ?string $model = StockDataMaster::class;

    public static function getColumns(): array
    {
        return [
            ImportColumn::make('plant')
                ->requiredMapping()
                ->exampleHeader('PLANT CODE')
                ->examples(['1000', '1000'])
                ->label('PLANT CODE')
                ->relationship(resolveUsing: 'code')
                ->rules(['required']),
            ImportColumn::make('type')
                ->requiredMapping()
                ->exampleHeader('TYPE')
                ->examples(['FG', 'NON-FG'])
                ->label('TYPE'),
            ImportColumn::make('location')
                ->requiredMapping()
                ->exampleHeader('LOCATION')
                ->examples(['2001', '2002'])
                ->label('LOCATION')
                ->rules(['required']),
            ImportColumn::make('item_reference')
                ->requiredMapping()
                ->exampleHeader('ITEM CODE')
                ->examples(['123456', '246118'])
                ->label('ITEM CODE')
                ->rules(['required']),
            ImportColumn::make('serial_number')
                ->requiredMapping()
                ->exampleHeader('SERIAL NUMBER')
                ->examples(['200235236622', '200235236623'])
                ->label('SERIAL NUMBER'),
            ImportColumn::make('batch')
                ->requiredMapping()
                ->exampleHeader('BATCH')
                ->examples(['20102', '20103'])
                ->label('BATCH'),
            ImportColumn::make('quantity')
                ->requiredMapping()
                ->exampleHeader('QUANTITY')
                ->examples(['1', '1'])
                ->label('QUANTITY'),
            ImportColumn::make('doc_no')
                ->requiredMapping()
                ->exampleHeader('DOCUMENT NUMBER')
                ->examples(['82128', '21222'])
                ->label('DOCUMENT NUMBER'),
        ];
    }

    public function resolveRecord(): ?StockDataMaster
    {
        $warnMsg = [];
        $plantId = null;
        $stickId = null;

        $plantCod = $this->data['plant'];
        $typeValue = $this->data['type'];
        $iCode = trim($this->data['item_reference']) ?? null;
        $location = trim($this->data['location']) ?? null;
        $serialNumber = trim($this->data['serial_number']) ?? null;
        $batch = trim($this->data['batch']) ?? null;
        $quantity = trim($this->data['quantity']) ?? null;
        $docNo = trim($this->data['doc_no']) ?? null;

        $user = Filament::auth()->user();

        $operatorName = $user->name;

        if ($plantCod == null || $plantCod == '') {
            $warnMsg[] = "Plant code can't be empty!";
        } elseif ($typeValue == null || $typeValue == '') {
            $warnMsg[] = "Type can't be empty!";
        } elseif ($iCode == null || $iCode == '') {
            $warnMsg[] = "Item code can't be empty!";
        } elseif ($location == null || $location == '') {
            $warnMsg[] = "Location can't be empty!";
        } elseif ($serialNumber == null || $serialNumber == '') {
            $warnMsg[] = "Serial number can't be empty!";
        }
        // else if ($batch == null || $batch == '') {
        //     $warnMsg[] = "Batch can't be empty!";
        // }
        elseif ($quantity == null || $quantity == '') {
            $warnMsg[] = "Quantity can't be empty!";
        }
        // else if ($docNo == null || $docNo == '') {
        //     $warnMsg[] = "Doc No can't be empty!";
        // }

        if (Str::length($plantCod) > 0 && (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod))) {
            $warnMsg[] = 'Invalid plant code found!';
        } elseif (Str::length($plantCod) > 0) {
            $plant = Plant::where('code', $plantCod)->first();
            if (! $plant) {
                $warnMsg[] = 'Plant code not found!';
            } else {
                $plantId = $plant->id;
            }
        }

        if (Str::length($iCode) > 0 && (Str::length($iCode) < 6 || ! ctype_alnum($iCode))) {
            $warnMsg[] = 'Invalid item code found!';
        } elseif ($plantId) {
            $itemCode = Item::where('code', $iCode)->first();
            if (! $itemCode) {
                $warnMsg[] = 'Item code not found in item master!';
            } else {
                $itemCode = Item::where('code', $iCode)->where('plant_id', $plantId)->first();
                if (! $itemCode) {
                    $warnMsg[] = 'Item code not found in item master for the given plant!';
                } else {
                    $itemId = $itemCode->id;
                    $itemCode = StickerMaster::where('item_id', $itemId)->first();
                    if (! $itemCode) {
                        $warnMsg[] = 'Item code not found in sticker master!';
                    } else {
                        if ($plantId) {
                            $itemCode = StickerMaster::where('item_id', $itemId)->where('plant_id', $plantId)->first();
                            if (! $itemCode) {
                                $warnMsg[] = 'Item code not found in sticker master for the given plant!';
                            }
                        }
                    }
                }
            }
        }

        $typeValue = strtoupper($typeValue);

        if (! in_array($typeValue, ['FG', 'NON-FG'])) {
            $warnMsg[] = 'Invalid type found! It should be either FG or NON-FG.';
        } elseif (Str::length($location) < 4) {
            $warnMsg[] = 'Location should contain minimum 4 digits!';
        } elseif (! ctype_digit((string) $location)) {
            $warnMsg[] = 'Location must be an integer!';
        } elseif (Str::length($serialNumber) < 9) {
            $warnMsg[] = 'Serial number should contain minimum 9 digits!';
        } elseif (! ctype_alnum($serialNumber)) {
            $warnMsg[] = 'Serial number should contain alpha-numeric values!';
        } elseif (! ctype_digit((string) $quantity) || (int) $quantity <= 0) {
            $warnMsg[] = 'Quantity must be an integer and greater than 0!';
        }

        if ($batch) {
            if (Str::length($batch) < 5) {
                $warnMsg[] = 'Batch should contain minimum 5 digits!';
            }
        }

        if ($docNo) {
            if (Str::length($docNo) < 5) {
                $warnMsg[] = 'Document number contain minimum 5 digits!';
            }
        }

        if (! empty($warnMsg)) {
            throw new RowImportFailedException(implode(', ', $warnMsg));
        }

        $type = match ($typeValue) {
            'FG' => '0',
            'NON-FG' => '1',
            default => null,
        };

        $stickId = $itemCode->id;

        $record = StockDataMaster::where([
            'plant_id' => $plantId,
            'sticker_master_id' => $stickId,
            'serial_number' => $serialNumber,
        ])->first();

        if ($record) {

            $record->update([
                'type' => $type,
                'location' => $location ?? null,
                'batch' => $batch ?? null,
                'quantity' => $quantity ?? null,
                'doc_no' => $docNo ?? null,
                'updated_by' => $operatorName,
            ]);

        } else {

            StockDataMaster::create([
                'plant_id' => $plantId,
                'sticker_master_id' => $stickId,
                'type' => $type,
                'location' => $location ?? null,
                'serial_number' => $serialNumber ?? null,
                'batch' => $batch ?? null,
                'quantity' => $quantity ?? null,
                'doc_no' => $docNo ?? null,
                'created_by' => $operatorName,
                'updated_by' => $operatorName,
            ]);
        }

        return null;
    }

    public static function getCompletedNotificationBody(Import $import): string
    {
        $body = 'Your stock data master import has completed and '.number_format($import->successful_rows).' '.str('row')->plural($import->successful_rows).' imported.';

        if ($failedRowsCount = $import->getFailedRowsCount()) {
            $body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to import.';
        }

        return $body;
    }
}
