<?php

namespace App\Filament\Imports;

use App\Models\Item;
use App\Models\MotorTestingMaster;
use App\Models\Plant;
use App\Models\User;
use DateTime;
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 MotorTestingMasterImporter extends Importer
{
    protected static ?string $model = MotorTestingMaster::class;

    public static function getColumns(): array
    {
        return [
            ImportColumn::make('item')
                ->requiredMapping()
                ->exampleHeader('Item Code')
                ->example(['123456', '123457', '123458'])
                ->label('Item Code')
                ->relationship(resolveUsing: 'code')
                ->rules(['required']),
            ImportColumn::make('subassembly_code')
                ->requiredMapping()
                ->exampleHeader('Subassembly Code')
                ->example(['123456'])
                ->label('Subassembly Code')
                ->rules(['required']),
            ImportColumn::make('isi_model')
                ->requiredMapping()
                ->boolean()
                ->exampleHeader('ISI Model')
                ->example(['Y', 'N', 'Y'])
                ->label('ISI Model')
                ->rules(['boolean']),
            ImportColumn::make('phase')
                ->requiredMapping()
                ->exampleHeader('Phase')
                ->example(['Single', 'Three', 'Single'])
                ->label('Phase')
                ->rules(['required']),
            ImportColumn::make('hp')
                ->requiredMapping()
                ->exampleHeader('HP')
                ->example(['5', '10', '5'])
                ->label('HP')
                ->rules(['required']),
            ImportColumn::make('kw')
                ->requiredMapping()
                ->exampleHeader('KW')
                ->example(['5', '7.5', '5'])
                ->label('KW')
                ->rules(['required']),
            ImportColumn::make('volt')
                ->requiredMapping()
                ->exampleHeader('Volt')
                ->example(['230', '380', '230'])
                ->label('Volt')
                ->rules(['required']),
            ImportColumn::make('current')
                ->requiredMapping()
                ->exampleHeader('Current')
                ->example(['7', '21.8', '7'])
                ->label('Current')
                ->rules(['required']),
            ImportColumn::make('rpm')
                ->requiredMapping()
                ->exampleHeader('RPM')
                ->example(['2500', '3420', '2500'])
                ->label('RPM')
                ->rules(['required']),
            ImportColumn::make('torque')
                ->requiredMapping()
                ->exampleHeader('Torque')
                ->example(['0.5', '1.25', '0.5'])
                ->label('Torque')
                ->rules(['required']),
            ImportColumn::make('frequency')
                ->requiredMapping()
                ->exampleHeader('Frequency')
                ->label('Frequency')
                ->example(['50', '60', '50'])
                ->rules(['required']),
            ImportColumn::make('connection')
                ->requiredMapping()
                ->exampleHeader('Connection')
                ->label('Connection')
                ->example(['Star', 'Star-Delta', 'Delta'])
                ->rules(['required']),
            ImportColumn::make('ins_res_limit')
                ->requiredMapping()
                ->exampleHeader('Insulation Resistance Limit')
                ->label('Insulation Resistance Limit')
                ->example(['1000', '2', '1000'])
                ->rules(['required']),
            ImportColumn::make('ins_res_type')
                ->requiredMapping()
                ->exampleHeader('Insulation Resistance Type')
                ->label('Insulation Resistance Type')
                ->example(['O', 'G', 'O'])
                ->rules(['required']),
            ImportColumn::make('routine_test_time')
                ->requiredMapping()
                ->exampleHeader('Routine Test Time')
                ->label('Routine Test Time')
                ->example(['00:40:00', '00:40:00', '00:40:00'])
                ->rules(['required']),
            ImportColumn::make('res_ry_ll')
                ->requiredMapping()
                ->exampleHeader('Resistance RY LL')
                ->label('Resistance RY LL')
                ->example(['0.05', '0.05', '0.05'])
                ->rules(['required']),
            ImportColumn::make('res_ry_ul')
                ->requiredMapping()
                ->exampleHeader('Resistance RY UL')
                ->label('Resistance RY UL')
                ->example(['99', '99', '99'])
                ->rules(['required']),
            ImportColumn::make('res_yb_ll')
                ->requiredMapping()
                ->exampleHeader('Resistance YB LL')
                ->label('Resistance YB LL')
                ->example(['0.05', '0.05', '0.05'])
                ->rules(['required']),
            ImportColumn::make('res_yb_ul')
                ->requiredMapping()
                ->exampleHeader('Resistance YB UL')
                ->label('Resistance YB UL')
                ->example(['99', '99', '99'])
                ->rules(['required']),
            ImportColumn::make('res_br_ll')
                ->requiredMapping()
                ->exampleHeader('Resistance BR LL')
                ->label('Resistance BR LL')
                ->example(['0.05', '0.05', '0.05'])
                ->rules(['required']),
            ImportColumn::make('res_br_ul')
                ->requiredMapping()
                ->exampleHeader('Resistance BR UL')
                ->label('Resistance BR UL')
                ->example(['99', '99', '99'])
                ->rules(['required']),
            ImportColumn::make('lock_volt_limit')
                ->requiredMapping()
                ->exampleHeader('Lock Volt Limit')
                ->label('Lock Volt Limit')
                ->example(['80', '100', '80'])
                ->rules(['required']),
            ImportColumn::make('leak_cur_limit')
                ->requiredMapping()
                ->exampleHeader('Leak Current Limit')
                ->label('Leak Current Limit')
                ->example(['50', '50', '50'])
                ->rules(['required']),
            ImportColumn::make('lock_cur_ll')
                ->requiredMapping()
                ->exampleHeader('Lock Current LL')
                ->label('Lock Current LL')
                ->example(['10', '12.5', '10'])
                ->rules(['required']),
            ImportColumn::make('lock_cur_ul')
                ->requiredMapping()
                ->exampleHeader('Lock Current UL')
                ->label('Lock Current UL')
                ->example(['15', '14.6', '15'])
                ->rules(['required']),
            ImportColumn::make('noload_cur_ll')
                ->requiredMapping()
                ->exampleHeader('No Load Current LL')
                ->label('No Load Current LL')
                ->example(['3', '5.9', '3'])
                ->rules(['required']),
            ImportColumn::make('noload_cur_ul')
                ->requiredMapping()
                ->exampleHeader('No Load Current UL')
                ->label('No Load Current UL')
                ->example(['15', '6.9', '15'])
                ->rules(['required']),
            ImportColumn::make('noload_pow_ll')
                ->requiredMapping()
                ->exampleHeader('No Load Power LL')
                ->label('No Load Power LL')
                ->example(['250', '850', '250'])
                ->rules(['required']),
            ImportColumn::make('noload_pow_ul')
                ->requiredMapping()
                ->exampleHeader('No Load Power UL')
                ->label('No Load Power UL')
                ->example(['500', '1200', '500'])
                ->rules(['required']),
            ImportColumn::make('noload_spd_ll')
                ->requiredMapping()
                ->exampleHeader('No Load Speed LL')
                ->label('No Load Speed LL')
                ->example(['2000', '2500', '2000'])
                ->rules(['required']),
            ImportColumn::make('noload_spd_ul')
                ->requiredMapping()
                ->exampleHeader('No Load Speed UL')
                ->label('No Load Speed UL')
                ->example(['4000', '3500', '4000'])
                ->rules(['required']),
            ImportColumn::make('plant')
                ->requiredMapping()
                ->exampleHeader('Plant Code')
                ->example(['1000', '1010', '1020'])
                ->label('Plant Code')
                ->relationship(resolveUsing: 'code')
                ->rules(['required']),
            // ImportColumn::make('created_by')
            //     ->requiredMapping()
            //     ->exampleHeader('Created By')
            //     ->example([Filament::auth()->user()->name, Filament::auth()->user()->name, Filament::auth()->user()->name])
            //     ->label('Created By')
            //     ->rules(['required']),
            // ImportColumn::make('updated_by')
            //     ->requiredMapping()
            //     ->exampleHeader('Updated By')
            //     ->example([Filament::auth()->user()->name, Filament::auth()->user()->name, Filament::auth()->user()->name])
            //     ->label('Updated By')
            //     ->rules(['required']),
        ];
    }

    public function resolveRecord(): ?MotorTestingMaster
    {
        $warnMsg = [];
        $plantCod = trim($this->data['plant']);
        $iCode = trim($this->data['item']);
        $sCode = trim($this->data['subassembly_code']);
        $isiModel = trim($this->data['isi_model']);
        $phase = trim($this->data['phase']);
        $kw = trim($this->data['kw']);
        $hp = trim($this->data['hp']);
        $volt = trim($this->data['volt']);
        $current = trim($this->data['current']);
        $rpm = trim($this->data['rpm']);
        $torque = trim($this->data['torque']);
        $frequency = trim($this->data['frequency']);
        $connection = trim($this->data['connection']);
        $insResType = trim($this->data['ins_res_type']);
        $insResLimit = trim($this->data['ins_res_limit']);
        $routineTestTime = trim($this->data['routine_test_time']);
        $resRyLl = trim($this->data['res_ry_ll']);
        $resRyUl = trim($this->data['res_ry_ul']);
        $resYbLl = trim($this->data['res_yb_ll']);
        $resYbUl = trim($this->data['res_yb_ul']);
        $resBrLl = trim($this->data['res_br_ll']);
        $resBrUl = trim($this->data['res_br_ul']);
        $lockVoltLimit = trim($this->data['lock_volt_limit']);
        $leakCurLimit = trim($this->data['leak_cur_limit']);
        $lockCurLl = trim($this->data['lock_cur_ll']);
        $lockCurUl = trim($this->data['lock_cur_ul']);
        $noloadCurLl = trim($this->data['noload_cur_ll']);
        $noloadCurUl = trim($this->data['noload_cur_ul']);
        $noloadPowLl = trim($this->data['noload_pow_ll']);
        $noloadPowUl = trim($this->data['noload_pow_ul']);
        $noloadSpdLl = trim($this->data['noload_spd_ll']);
        $noloadSpdUl = trim($this->data['noload_spd_ul']);
        $createdBy = Filament::auth()->user()->name;
        $updatedBy = Filament::auth()->user()->name;

        $plant = null;
        if (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod)) {
            $warnMsg[] = 'Invalid plant code found';
        } elseif (Str::length($iCode) < 6 || ! ctype_alnum($iCode)) {
            $warnMsg[] = 'Invalid item code found';
        } elseif (Str::length($sCode) > 0 && (Str::length($sCode) < 6 || ! ctype_alnum($sCode))) {
            $warnMsg[] = 'Invalid sub-assembly code found';
        } else {
            $plant = Plant::where('code', $plantCod)->first();
            $codeExist = Item::where('code', $iCode)->first();
            if ($plant) {
                $iCode = Item::where('code', $iCode)->where('plant_id', $plant->id)->first();
            }
            if (! $plant) {
                $warnMsg[] = 'Plant not found';
            } elseif (! $codeExist) {
                $warnMsg[] = 'Item code not found';
            } elseif (! $iCode) {
                $warnMsg[] = 'Item code not found for choosed plant';
            } else {
                $isiModel = (Str::length($isiModel) == 1 && ctype_alnum($isiModel) && ($isiModel == '1' || $isiModel == 'Y' || $isiModel == 'y')) ? true : false;

                if (Str::length($phase) <= 0 || ($phase != 'Single' && $phase != 'Three')) {// !is_string($phase) ||
                    $warnMsg[] = 'Invalid phase found';
                }
                if (Str::length($hp) <= 0 || ! is_numeric($hp)) {
                    $warnMsg[] = 'Invalid HP found';
                }
                if (Str::length($kw) <= 0 || ! is_numeric($kw)) {
                    $warnMsg[] = 'Invalid KW found';
                }
                if (Str::length($volt) <= 0 || ! is_numeric($volt)) {
                    $warnMsg[] = 'Invalid volt found';
                }
                if (Str::length($current) <= 0 || ! is_numeric($current)) {
                    $warnMsg[] = 'Invalid current found';
                }
                if (Str::length($rpm) <= 0 || ! is_numeric($rpm)) {
                    $warnMsg[] = 'Invalid RPM found';
                }
                if (Str::length($torque) <= 0 || ! is_numeric($torque)) {
                    $warnMsg[] = 'Invalid torque found';
                }
                if (Str::length($frequency) <= 0 || ! is_numeric($frequency)) {
                    $warnMsg[] = 'Invalid frequency found';
                }
                if (Str::length($connection) <= 0 || ($connection != 'Star-Delta' && $connection != 'Star' && $connection != 'Delta')) {
                    $warnMsg[] = 'Invalid connection found';
                }
                if (Str::length($insResLimit) <= 0 || ! is_numeric($insResLimit)) {
                    $warnMsg[] = 'Invalid insulation resistance limit found';
                }
                if (Str::length($insResType) <= 0 || ($insResType != 'O' && $insResType != 'M' && $insResType != 'G')) {
                    $warnMsg[] = 'Invalid insulation resistance type found';
                }
                if (Str::length($routineTestTime) <= 0 || ! isValidTimeFormat($routineTestTime)) {
                    $warnMsg[] = 'Invalid routine test time found';
                }
                if (Str::length($resRyLl) <= 0 || ! is_numeric($resRyLl)) {
                    $warnMsg[] = 'Invalid resistance RY lower limit found';
                }
                if (Str::length($resRyUl) <= 0 || ! is_numeric($resRyUl)) {
                    $warnMsg[] = 'Invalid resistance RY upper limit found';
                }
                if (Str::length($resYbLl) <= 0 || ! is_numeric($resYbLl)) {
                    $warnMsg[] = 'Invalid resistance YB lower limit found';
                }
                if (Str::length($resYbUl) <= 0 || ! is_numeric($resYbUl)) {
                    $warnMsg[] = 'Invalid resistance YB upper limit found';
                }
                if (Str::length($resBrLl) <= 0 || ! is_numeric($resBrLl)) {
                    $warnMsg[] = 'Invalid resistance BR lower limit found';
                }
                if (Str::length($resBrUl) <= 0 || ! is_numeric($resBrUl)) {
                    $warnMsg[] = 'Invalid resistance BR upper limit found';
                }
                if (Str::length($lockVoltLimit) <= 0 || ! is_numeric($lockVoltLimit)) {
                    $warnMsg[] = 'Invalid locked volt limit found';
                }
                if (Str::length($leakCurLimit) <= 0 || ! is_numeric($leakCurLimit)) {
                    $warnMsg[] = 'Invalid leakage current limit found';
                }
                if (Str::length($lockCurLl) <= 0 || ! is_numeric($lockCurLl)) {
                    $warnMsg[] = 'Invalid locked current lower limit found';
                }
                if (Str::length($lockCurUl) <= 0 || ! is_numeric($lockCurUl)) {
                    $warnMsg[] = 'Invalid locked current upper limit found';
                }
                if (Str::length($noloadCurLl) <= 0 || ! is_numeric($noloadCurLl)) {
                    $warnMsg[] = 'Invalid no load current lower limit found';
                }
                if (Str::length($noloadCurUl) <= 0 || ! is_numeric($noloadCurUl)) {
                    $warnMsg[] = 'Invalid no load current upper limit found';
                }
                if (Str::length($noloadPowLl) <= 0 || ! is_numeric($noloadPowLl)) {
                    $warnMsg[] = 'Invalid no load power lower limit found';
                }
                if (Str::length($noloadPowUl) <= 0 || ! is_numeric($noloadPowUl)) {
                    $warnMsg[] = 'Invalid no load power upper limit found';
                }
                if (Str::length($noloadSpdLl) <= 0 || ! is_numeric($noloadSpdLl)) {
                    $warnMsg[] = 'Invalid no load speed lower limit found';
                }
                if (Str::length($noloadSpdUl) <= 0 || ! is_numeric($noloadSpdUl)) {
                    $warnMsg[] = 'Invalid no load speed upper limit found';
                }

                $oldCode = MotorTestingMaster::where('item_id', $iCode->id)->where('plant_id', $plant->id)->first();

                if ($oldCode) {
                    $created = $oldCode->created_by ? User::where('name', $oldCode->created_by)->first() : null;
                    if (! $created) {
                        $warnMsg[] = 'Created by not found on update';
                    } else {
                        $createdBy = $created->name;
                    }
                }
            }
        }

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

        MotorTestingMaster::updateOrCreate([
            'plant_id' => $plant->id,
            'item_id' => $iCode->id,
        ],
            [
                'subassembly_code' => $sCode,
                'isi_model' => $isiModel,
                'phase' => $phase,
                'kw' => $kw,
                'hp' => $hp,
                'volt' => $volt,
                'current' => $current,
                'rpm' => $rpm,
                'torque' => $torque,
                'frequency' => $frequency,
                'connection' => $connection,
                'ins_res_limit' => $insResLimit,
                'ins_res_type' => $insResType,
                'routine_test_time' => $routineTestTime,
                'res_ry_ll' => $resRyLl,
                'res_ry_ul' => $resRyUl,
                'res_yb_ll' => $resYbLl,
                'res_yb_ul' => $resYbUl,
                'res_br_ll' => $resBrLl,
                'res_br_ul' => $resBrUl,
                'lock_volt_limit' => $lockVoltLimit,
                'leak_cur_limit' => $leakCurLimit,
                'lock_cur_ll' => $lockCurLl,
                'lock_cur_ul' => $lockCurUl,
                'noload_cur_ll' => $noloadCurLl,
                'noload_cur_ul' => $noloadCurUl,
                'noload_pow_ll' => $noloadPowLl,
                'noload_pow_ul' => $noloadPowUl,
                'noload_spd_ll' => $noloadSpdLl,
                'noload_spd_ul' => $noloadSpdUl,
                'created_by' => $createdBy,
                'updated_by' => $updatedBy,
            ]
        );

        return null;
        // // return MotorTestingMaster::firstOrNew([
        // //     // Update existing records, matching them by `$this->data['column_name']`
        // //     'email' => $this->data['email'],
        // // ]);

        // return new MotorTestingMaster();
    }

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

function isValidTimeFormat($time)
{
    // If time starts with a single digit hour without leading zero, pad it
    if (preg_match('/^\d(:\d{2}:\d{2})$/', $time, $matches)) {
        $time = '0'.$time;
    }

    $dateTime = DateTime::createFromFormat('H:i:s', $time);

    return $dateTime && $dateTime->format('H:i:s') === $time;
}
