<?php

namespace App\Filament\Imports;

use App\Models\Company;
use App\Models\Plant;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
use Str;

class PlantImporter extends Importer
{
    protected static ?string $model = Plant::class;

    public static function getColumns(): array
    {
        return [
            ImportColumn::make('company')
                ->requiredMapping()
                ->exampleHeader('COMPANY')
                ->example('C.R.I. Pumps Private Limited')
                ->label('COMPANY')
                ->relationship(resolveUsing: 'name')
                ->rules(['required']),
            ImportColumn::make('code')
                ->requiredMapping()
                ->numeric()
                ->exampleHeader('CODE')
                ->example('1000')
                ->label('CODE')
                ->rules(['required']),
            ImportColumn::make('name')
                ->requiredMapping()
                ->exampleHeader('NAME')
                ->example('Ransar Industries-I')
                ->label('NAME')
                ->rules(['required']),
            ImportColumn::make('warehouse_number')
                ->requiredMapping()
                ->exampleHeader('WAREHOUSE_NUMBER')
                ->example('001')
                ->label('WAREHOUSE_NUMBER')
                ->rules(['required']),
            ImportColumn::make('address')
                ->requiredMapping()
                ->exampleHeader('ADDRESS')
                ->example('7/51-A, Keeranatham Road, Saravanampatty, Coimbatore - 641035')
                ->label('ADDRESS')
                ->rules(['required']),
        ];
    }

    public function resolveRecord(): ?Plant
    {
        $warnMsg = [];
        $compId = null;
        $comp = trim($this->data['company']) ?? null;
        $code = trim($this->data['code']) ?? null;
        $name = trim($this->data['name']) ?? null;
        $wareHouseNo = trim($this->data['warehouse_number']) ?? null;
        $addr = trim($this->data['address']) ?? null;

        if ($comp == null || $comp == '' || ! $comp) {
            $warnMsg[] = "Company name can't be empty!";
        } elseif (Str::length($comp) < 5) {
            $warnMsg[] = 'Company name should contain at least 5 characters!';
        }
        if ($code == null || $code == '') {
            $warnMsg[] = "Code can't be empty!";
        } elseif (! is_numeric($code)) {
            $warnMsg[] = 'Code should contain only numeric values!';
        } elseif (Str::length($code) < 4 || Str::length($code) > 7) {
            $warnMsg[] = 'Code must be between 4 and 7 digits only!';
        } elseif (! preg_match('/^[1-9]\d{3,6}$/', $code)) {
            $warnMsg[] = 'Invalid plant code found!';
        }
        if ($name == null || $name == '' || ! $name) {
            $warnMsg[] = "Name can't be empty!";
        } elseif (Str::length($name) < 5) {
            $warnMsg[] = 'Name should contain at least 5 characters!';
        }
        if ($wareHouseNo == null || $wareHouseNo == '' || ! $wareHouseNo) {
            // $warnMsg[] = "Warehouse number can't be empty!";
        } elseif (! is_numeric($wareHouseNo)) {
            $warnMsg[] = 'Warehouse number should contain only numeric values!';
        } elseif (Str::length($wareHouseNo) == 3) {
            $warnMsg[] = 'Warehouse number must contain 3 digits only!';
        }
        if ($addr == null || $addr == '' || ! $addr) {
            $warnMsg[] = "Address can't be empty!";
        } elseif (Str::length($addr) < 5) {
            $warnMsg[] = 'Address should contain at least 5 characters!';
        }

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

        $company = Company::where('name', $comp)->first();
        if (! $company) {
            throw new RowImportFailedException('Company name not found!');
        } else {
            $compId = $company->id;
        }

        $plantCN = Plant::where('code', $code)->where('name', $name)->first();
        $plantCW = Plant::where('code', $code)->where('warehouse_number', $wareHouseNo)->first();
        if (! $plantCN) {
            $plantCode = Plant::where('code', $code)->first();
            $plantName = Plant::where('name', $name)->first();
            if ($plantName) {
                throw new RowImportFailedException('Duplicate plant name found!');
            } elseif ($plantCode) {
                throw new RowImportFailedException('Duplicate plant code found!');
            } elseif (! $plantCW) {
                $wareHouse = Plant::where('warehouse_number', $wareHouseNo)->first();
                if ($wareHouse) {
                    throw new RowImportFailedException('Duplicate warehouse number found!');
                }
            }
        } elseif (! $plantCW) {
            $wareHouse = Plant::where('warehouse_number', $wareHouseNo)->first();
            if ($wareHouse) {
                throw new RowImportFailedException('Duplicate warehouse number found!');
            }
        }

        return Plant::updateOrCreate([
            'code' => $code,
            'name' => $name,
        ],
            [
                'warehouse_number' => $wareHouseNo,
                'address' => $addr,
                'company_id' => $compId,
            ]
        );
        // return Plant::firstOrNew([
        //     // Update existing records, matching them by `$this->data['column_name']`
        //     'email' => $this->data['email'],
        // ]);

        // return new Plant();
    }

    public static function getCompletedNotificationBody(Import $import): string
    {
        $body = 'Your plant 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;
    }
}
