<?php

namespace App\Filament\Imports;

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

class CustomerPoMasterImporter extends Importer
{
    protected static ?string $model = CustomerPoMaster::class;

    protected array $importedPos = [];

    public static function getColumns(): array
    {
        return [
            ImportColumn::make('plant')
                ->requiredMapping()
                ->exampleHeader('Plant Code')
                ->example('1000')
                ->label('Plant Code')
                ->relationship(resolveUsing: 'code')
                ->rules(['required']),
            ImportColumn::make('item')
                ->requiredMapping()
                ->exampleHeader('Item Code')
                ->example('630214')
                ->label('Item Code')
                ->relationship(resolveUsing: 'code')
                ->rules(['required']),
            ImportColumn::make('customer_po')
                ->requiredMapping()
                ->exampleHeader('Customer PO')
                ->example('1JA0029512')
                ->label('Customer PO')
                ->rules(['required']),
            ImportColumn::make('customer_name')
                ->requiredMapping()
                ->exampleHeader('Customer Name')
                ->example('KANKARIA MACHINERY STORE')
                ->label('Customer Name')
                ->rules(['required']),
            ImportColumn::make('quantity')
                ->requiredMapping()
                ->exampleHeader('Quantity')
                ->example('5')
                ->label('Quantity')
                ->rules(['required']),
            // ImportColumn::make('created_by')
            //     ->requiredMapping()
            //     ->exampleHeader('Created By')
            //     ->example('Admin')
            //     ->label('Created By')
            //     ->rules(['required']),
        ];
    }

    public function resolveRecord(): ?CustomerPoMaster
    {
        $warnMsg = [];
        $plantCod = $this->data['plant'];
        $plant = null;
        $item = null;
        $customerPo = trim($this->data['customer_po']);
        $customerName = trim($this->data['customer_name']);

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

        if (Str::length($this->data['customer_po']) < 9) {
            $warnMsg[] = 'Invalid Customer PO number found';
        }

        if (empty($this->data['customer_po'])) {
            $warnMsg[] = 'Customer PO cannot be empty.';
        }

        if (isset($this->importedPos[$customerPo])) {

            if (strtolower(trim($this->importedPos[$customerPo])) != strtolower($customerName)){
                $warnMsg[] = "Customer PO '{$customerPo}' has multiple customer names in the import file.";
            }
        }
        else {
            $this->importedPos[$customerPo] = $customerName;
        }

        $existingPo = CustomerPoMaster::where('plant_id', $plant->id)->where('customer_po', $this->data['customer_po'])->first();

        if ($existingPo && trim(strtolower($existingPo->customer_name)) != trim(strtolower($this->data['customer_name'])))
        {
            $warnMsg[] =  "Customer PO '{$this->data['customer_po']}' is already mapped to customer '{$existingPo->customer_name}'.";
        }

        $existingPoItem = CustomerPoMaster::where('plant_id', $plant->id)->where('item_id', $item->id)->where('customer_po', $this->data['customer_po'])->where('customer_name', $this->data['customer_name'])->first();

        if ($existingPoItem)
        {
            $warnMsg[] =  "Customer PO '{$this->data['customer_po']}' is already exist with item code '{$this->data['item']}' and customer name '{$this->data['customer_name']}'.";
        }

        // $user = User::where('name', $this->data['created_by'])->first();
        // if (! $user) {
        //     $warnMsg[] = 'User not found';
        // }

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

        $operatorName = $user->name;

        if (! empty($warnMsg)) {
            throw new RowImportFailedException(implode(', ', $warnMsg));
        }
        //else { // if (empty($warnMsg))
        //     $grMaster = GrMaster::where('plant_id', $plant->id)
        //         ->where('serial_number', $this->data['serial_number'])
        //         ->latest()
        //         ->first();

        //     if ($grMaster) {
        //         throw new RowImportFailedException('Serial number already exist!');
        //     }
        // }

        CustomerPoMaster::updateOrCreate([
            'plant_id' => $plant->id,
            'item_id' => $item->id,
            'customer_po' => $this->data['customer_po'],
            'customer_name' => $this->data['customer_name'],
            'quantity' => $this->data['quantity'] ?? null,
            'created_by' => $operatorName,
        ]);

        return null;

        // return new CustomerPoMaster();
    }

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