<?php

namespace App\Filament\Imports;

use App\Models\Item;
use App\Models\Line;
use App\Models\Machine;
use App\Models\Plant;
use App\Models\ProductCharacteristicsMaster;
use App\Models\User;
use App\Models\WorkGroupMaster;
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 ProductCharacteristicsMasterImporter extends Importer
{
    protected static ?string $model = ProductCharacteristicsMaster::class;

    public static function getColumns(): array
    {
        return [
            ImportColumn::make('plant')
                ->label('PLANT CODE')
                ->requiredMapping()
                ->exampleHeader('PLANT CODE')
                ->example(['1000', '1000'])
                ->relationship(resolveUsing: 'code')
                ->rules(['required']),
            ImportColumn::make('item')
                ->label('ITEM CODE')
                ->requiredMapping()
                ->exampleHeader('ITEM CODE')
                ->example(['123456', '123456'])
                ->relationship(resolveUsing: 'code')
                ->rules(['required']),
            ImportColumn::make('line')
                ->label('LINE NAME')
                ->requiredMapping()
                ->exampleHeader('LINE NAME')
                ->example(['4 inch pump line', '4 inch pump line'])
                ->relationship(resolveUsing: 'name')
                ->rules(['required']),
            ImportColumn::make('work_group_master_id')
                ->label('GROUP WORK CENTER')
                ->requiredMapping()
                ->exampleHeader('GROUP WORK CENTER')
                ->example(['RMGSTR01', 'RMGSTR01'])
                ->relationship(resolveUsing: 'name')
                ->rules(['required']),
            ImportColumn::make('machine')
                ->label('WORK CENTER')
                ->requiredMapping()
                ->exampleHeader('WORK CENTER')
                ->example(['RMISTR01', 'RMISTR02'])
                ->relationship(resolveUsing: 'work_center')
                ->rules(['required']),
            ImportColumn::make('characteristics_type')
                ->label('CHARACTERISTICS TYPE')
                ->requiredMapping()
                ->exampleHeader('CHARACTERISTICS TYPE')
                ->example(['Product', 'Process'])
                ->rules(['required']),
            ImportColumn::make('name')
                ->label('CHARACTERISTICS NAME')
                ->requiredMapping()
                ->exampleHeader('CHARACTERISTICS NAME')
                ->example(['TEST01', 'TEST02'])
                ->rules(['required']),
            ImportColumn::make('category')
                ->label('CATEGORY')
                ->requiredMapping()
                ->exampleHeader('CATEGORY')
                ->example(['Open Pump', 'Submersible Pump']),
            ImportColumn::make('inspection_type')
                ->label('INSPECTION TYPE')
                ->requiredMapping()
                ->exampleHeader('INSPECTION TYPE')
                ->example(['Value', 'Visual'])
                ->rules(['required']),
            ImportColumn::make('lower')
                ->label('LOWER')
                ->requiredMapping()
                ->exampleHeader('LOWER')
                ->example(['5', '0'])
                ->rules(['required']),
            ImportColumn::make('middle')
                ->label('MIDDLE')
                ->requiredMapping()
                ->exampleHeader('MIDDLE')
                ->example(['10', '0'])
                ->rules(['required']),
            ImportColumn::make('upper')
                ->label('UPPER')
                ->requiredMapping()
                ->exampleHeader('UPPER')
                ->example(['15', '0'])
                ->rules(['required']),
            // ImportColumn::make('created_by'),
            // ImportColumn::make('updated_by'),

        ];
    }

    public function resolveRecord(): ?ProductCharacteristicsMaster
    {
        $warnMsg = [];
        $plantCod = trim($this->data['plant']) ?? null;
        $itemCod = trim($this->data['item']) ?? null;
        $lineNam = trim($this->data['line']) ?? null;
        $groupWorkCenter = trim($this->data['work_group_master_id']) ?? null;
        $workCenter = trim($this->data['machine']) ?? null;
        $charTyp = trim($this->data['characteristics_type']) ?? null;
        $charNam = trim($this->data['name']) ?? null;
        $category = trim($this->data['category']) ?? null;
        $inspectTyp = trim($this->data['inspection_type']) ?? null;
        $lower = trim($this->data['lower']) ?? null;
        $middle = trim($this->data['middle']) ?? null;
        $upper = trim($this->data['upper']) ?? null;
        $createdBy = Filament::auth()->user()->name;
        $updatedBy = null;

        $plantId = null;
        $itemId = null;
        $lineId = null;
        $workGroupMasterId = null;
        $machineId = null;

        if ($plantCod == null || $plantCod == '') {
            $warnMsg[] = "Plant code can't be empty!";
        } elseif (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod)) {
            $warnMsg[] = 'Invalid plant code found!';
        }
        if ($itemCod == null || $itemCod == '') {
            $warnMsg[] = "Item code can't be empty!";
        } elseif (Str::length($itemCod) < 6 || ! ctype_alnum($itemCod)) {
            $warnMsg[] = 'Invalid item code found!';
        }
        if ($lineNam == null || $lineNam == '') {
            $warnMsg[] = "Line name can't be empty!";
        }
        if ($groupWorkCenter == null || $groupWorkCenter == '') {
            $warnMsg[] = "Group work center can't be empty!";
        }
        if ($workCenter == null || $workCenter == '') {
            $warnMsg[] = "Work center can't be empty!";
        }
        if ($charTyp != 'Product' && $charTyp != 'Process') {
            $warnMsg[] = "Characteristics type must be either 'Product' or 'Process'!";
        }
        if ($charNam == null || $charNam == '') {
            $warnMsg[] = "Characteristics name can't be empty!";
        }
        if ($inspectTyp != 'Visual' && $inspectTyp != 'Value') {
            $warnMsg[] = "Inspection type must be either 'Visual' or 'Value'!";
        }
        if ($lower == null || $lower == '' || $middle == null || $middle == '' || $upper == null || $upper == '' || $upper == 0 || $upper == '0') {
            $lower = 0;
            $middle = 0;
            $upper = 0;
        }

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

        $plant = Plant::where('code', $plantCod)->first();
        if (! $plant) {
            $warnMsg[] = 'Plant code not found!';
        } else {
            $plantId = $plant->id;
            $itemExists = Item::where('code', $itemCod)->first();
            if (! $itemExists) {
                $warnMsg[] = 'Item code not found!';
            } else {
                $itemAgainstPlant = Item::where('code', $itemCod)->where('plant_id', $plantId)->first();
                if (! $itemAgainstPlant) {
                    $warnMsg[] = 'Item code not found for the given plant!';
                } else {
                    $itemId = $itemAgainstPlant->id;
                }
            }

            $lineExists = Line::where('name', $lineNam)->first();
            if (! $lineExists) {
                $warnMsg[] = 'Line name not found!';
            } else {
                $lineAgainstPlant = Line::where('name', $lineNam)->where('plant_id', $plantId)->first();
                if (! $lineAgainstPlant) {
                    $warnMsg[] = 'Line name not found for the given plant!';
                } else {
                    $lineId = $lineAgainstPlant->id;

                    $WorkgroupMaster = WorkGroupMaster::where('name', $groupWorkCenter)->first();
                    if (! $WorkgroupMaster) {
                        $warnMsg[] = 'Group work center not found!';
                    } else {
                        $WorkgroupMaster = WorkGroupMaster::where('name', $groupWorkCenter)->where('plant_id', $plantId)->first();
                        if (! $WorkgroupMaster) {
                            $warnMsg[] = 'Group work center not found for the given plant!';
                        } else {
                            $workGroupMasterId = $WorkgroupMaster->id;

                            // 2. Now check if this WorkGroupMaster id exists in ANY of the 10 columns
                            $existsInLine = Line::where('plant_id', $plantId)->where('id', $lineId)
                                ->where(function ($q) use ($workGroupMasterId) {
                                    for ($i = 1; $i <= 10; $i++) {
                                        $q->orWhere("work_group{$i}_id", $workGroupMasterId);
                                    }
                                })
                                ->exists();

                            if (! $existsInLine) {
                                $workGroupMasterId = null;
                                $warnMsg[] = "Group work center '{$WorkgroupMaster->name}' is not mapped for the given line!";
                            } else {
                                $workGroupMasterId = $WorkgroupMaster->id;

                                $machine = Machine::where('work_center', $workCenter)->first();
                                if (! $machine) {
                                    $warnMsg[] = 'Work center not found!';
                                } else {
                                    $machine = Machine::where('work_center', $workCenter)->where('plant_id', $plantId)->first();

                                    if (! $machine) {
                                        $warnMsg[] = 'Work center not found for the given plant!';
                                    } else {
                                        $machine = Machine::where('work_center', $workCenter)->where('plant_id', $plantId)->where('line_id', $lineId)->first();

                                        if (! $machine) {
                                            $warnMsg[] = "Work center '{$workCenter}' is not mapped for the given line!";
                                        } else {
                                            $machine = Machine::where('work_center', $workCenter)->where('plant_id', $plantId)->where('line_id', $lineId)->where('work_group_master_id', $workGroupMasterId)->first();

                                            if (! $machine) {
                                                $warnMsg[] = "Work center '{$workCenter}' is not mapped for the given group work center!";
                                            } else {
                                                $machineId = $machine->id;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            $user = User::where('name', $createdBy)->first();
            if (! $user) {
                $warnMsg[] = 'Created by user not found!';
            } else {
                $updatedBy = $createdBy;
            }

            if ($inspectTyp == 'Value') {
                if (is_null($upper) || is_null($lower) || is_null($middle)) {
                    $warnMsg[] = 'Upper, Lower, and Middle values are required.';
                } elseif (! is_numeric($upper) || ! is_numeric($lower) || ! is_numeric($middle)) {
                    $warnMsg[] = 'Upper, Lower, and Middle values must be numeric.';
                } else {
                    $lower = (float) $lower;
                    $middle = (float) $middle;
                    $upper = (float) $upper;
                    if ($lower == $upper) {
                        if ($lower != $middle) {
                            $warnMsg[] = "For 'Value' inspection type, values must satisfy: Lower = Middle = Upper.";
                        }
                    } elseif (! ($lower < $middle && $middle < $upper)) {
                        $warnMsg[] = "For 'Value' inspection type, values must satisfy: Lower < Middle < Upper.";
                    }
                }
            } else {
                $lower = 0;
                $middle = 0;
                $upper = 0;
            }
        }

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

        if ($machineId) {
            $record = ProductCharacteristicsMaster::where('plant_id', $plantId)->where('line_id', $lineId)->where('work_group_master_id', $workGroupMasterId)->where('machine_id', $machineId)->where('item_id', $itemId)->where('characteristics_type', $charTyp)->where('name', $charNam)->first();
            if ($record) {
                $createdBy = $record->created_by ?? $createdBy;
            }

            ProductCharacteristicsMaster::updateOrCreate(
                [
                    'plant_id' => $plantId,
                    'item_id' => $itemId,
                    'line_id' => $lineId,
                    'work_group_master_id' => $workGroupMasterId,
                    'machine_id' => $machineId,
                    'characteristics_type' => $charTyp,
                    'name' => $charNam,
                ],
                [
                    'category' => $category,
                    'inspection_type' => $inspectTyp,
                    'lower' => $lower,
                    'middle' => $middle,
                    'upper' => $upper,
                    'created_by' => $createdBy,
                    'updated_by' => $updatedBy,
                ]);
        }

        return null;

        // return new WorkGroupMaster();
        // return new ProductCharacteristicsMaster();
    }

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