<?php

namespace App\Filament\Imports;

use App\Models\EmployeeMaster;
use App\Models\Plant;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
use Filament\Facades\Filament;
use Str;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Carbon\Carbon;

class EmployeeMasterImporter extends Importer
{
    protected static ?string $model = EmployeeMaster::class;

    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('name')
                ->exampleHeader('EMPLOYEE NAME')
                ->example('John Doe')
                ->label('EMPLOYEE NAME'),
            ImportColumn::make('code')
                ->exampleHeader('EMPLOYEE ID')
                ->example('EMP001')
                ->label('EMPLOYEE ID'),
            ImportColumn::make('department')
                ->exampleHeader('DEPARTMENT')
                ->example('HR')
                ->label('DEPARTMENT'),
            // ImportColumn::make('designation')
            //     ->exampleHeader('DESIGNATION')
            //     ->example('Manager')
            //     ->label('DESIGNATION'),
            ImportColumn::make('email')
                ->exampleHeader('EMAIL')
                ->example('john.doe@example.com')
                ->label('EMAIL'),
            ImportColumn::make('mobile_number')
                ->exampleHeader('MOBILE NUMBER')
                ->example('1234567890')
                ->label('MOBILE NUMBER'),
        ];
    }

    public function resolveRecord(): ?EmployeeMaster
    {
        $warnMsg = [];
        $plantCod = trim($this->data['plant']) ?? '';
        $employeeName = trim($this->data['name']) ?? '';
        $employeeCode = trim($this->data['code']) ?? '';
        $employeeDepartment = trim($this->data['department']) ?? '';
        // $employeeDesignation = trim($this->data['designation']) ?? '';
        $employeeEmail = trim($this->data['email']) ?? '';
        $employeeMobile = trim($this->data['mobile_number']) ?? '';
        $createdBy = Filament::auth()->user()?->name ?? '';
        $updatedBy = $createdBy;

        $plantId = null;

        if ($plantCod == null || $plantCod == '' || ! $plantCod) {
            $warnMsg[] = "Plant code can't be empty!";
        } elseif (! is_numeric($plantCod)) {
            $warnMsg[] = "Plant code '{$plantCod}' should contain only numeric values!";
        } elseif (Str::length($plantCod) < 4 || Str::length($plantCod) > 7) {
            $warnMsg[] = "Plant code '{$plantCod}' must be between 4 and 7 digits only!";
        } elseif (! preg_match('/^[1-9]\d{3,6}$/', $plantCod)) {
            $warnMsg[] = "Invalid plant code '{$plantCod}' found!";
        } else {
            $plant = Plant::where('code', $plantCod)->first();
            if (! $plant) {
                $warnMsg[] = 'Plant not found!';
            } else {
                $plantId = $plant->id;
            }
        }

        if ($employeeCode == null || $employeeCode == '' || ! $employeeCode) {
            $warnMsg[] = "Employee ID can't be empty!";
        } elseif (Str::length($employeeCode) < 3 || Str::length($employeeCode) > 20) {
            $warnMsg[] = "Employee ID '{$employeeCode}' must be between 3 and 20 characters only!";
        }
        if ($employeeEmail != null && $employeeEmail != '' && ! filter_var($employeeEmail, FILTER_VALIDATE_EMAIL)) {
            $warnMsg[] = "Invalid email address '{$employeeEmail}' found!";
        }
        if ($employeeMobile != null && $employeeMobile != '' && ! is_numeric($employeeMobile)) {
            $warnMsg[] = "Mobile number '{$employeeMobile}' should contain only numeric values!";
        } elseif (Str::length($employeeMobile) < 10 || Str::length($employeeMobile) > 10) {
            $warnMsg[] = "Mobile number '{$employeeMobile}' must be exactly 10 digits!";
        }
        else
        {
            $existingMobile = EmployeeMaster::where('mobile_number', $employeeMobile)
                ->where('code', '!=', $employeeCode)
                ->first();

            if ($existingMobile) {
                $warnMsg[] = "Mobile number '{$employeeMobile}' is already assigned to another employee!";
            }
        }

        if (! empty($warnMsg)) {
            throw new RowImportFailedException(implode(', ', $warnMsg));
        }
        else
        {
            EmployeeMaster::updateOrCreate(
                [
                    'plant_id' => $plantId ?? null,
                    'code' => $employeeCode ?? null,
                ],
                [
                    'name' => $employeeName ?? null,
                    'email' => $employeeEmail ?? null,
                    'mobile_number' => $employeeMobile ?? null,
                    'department' => $employeeDepartment ?? null,
                    // 'designation' => $employeeDesignation ?? null,
                    'created_by' => $createdBy ?? null,
                    'updated_by' => $updatedBy ?? null,
                ]
            );
        }

        return null;
    }

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