<?php

namespace App\Filament\Imports;

use App\Models\Line;
use App\Models\Plant;
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 Str;

class LineImporter extends Importer
{
    protected static ?string $model = Line::class;

    public static function getColumns(): array
    {
        return [
            ImportColumn::make('name')
                ->requiredMapping()
                ->exampleHeader('Line Name')
                ->example('4 inch pump line')
                ->label('Line Name')
                ->rules(['required']),
            ImportColumn::make('type')
                ->requiredMapping()
                ->exampleHeader('Line Type')
                ->example('Domestic Assembly')
                ->label('Line Type')
                ->rules(['required']),
            ImportColumn::make('no_of_operation')
                ->requiredMapping()
                ->exampleHeader('No of Operation')
                ->example('10')
                ->label('No of Operation'),
            ImportColumn::make('work_group1_id')
                ->requiredMapping()
                ->exampleHeader('Work Group Center 1')
                ->example('RMGCGABC')
                ->label('Work Group Center 1'),
            ImportColumn::make('work_group2_id')
                ->requiredMapping()
                ->exampleHeader('Work Group Center 2')
                ->example('RMGCGABC1')
                ->label('Work Group Center 2'),
            ImportColumn::make('work_group3_id')
                ->requiredMapping()
                ->exampleHeader('Work Group Center 3')
                ->example('RMGCGABC2')
                ->label('Work Group Center 3'),
            ImportColumn::make('work_group4_id')
                ->requiredMapping()
                ->exampleHeader('Work Group Center 4')
                ->example('RMGCGABC1')
                ->label('Work Group Center 4'),
            ImportColumn::make('work_group5_id')
                ->requiredMapping()
                ->exampleHeader('Work Group Center 5')
                ->example('RMGCGABC5')
                ->label('Work Group Center 5'),
            ImportColumn::make('work_group6_id')
                ->requiredMapping()
                ->exampleHeader('Work Group Center 6')
                ->example('RMGCGABC6')
                ->label('Work Group Center 6'),
            ImportColumn::make('work_group7_id')
                ->requiredMapping()
                ->exampleHeader('Work Group Center 7')
                ->example('RMGCGABC7')
                ->label('Work Group Center 7'),
            ImportColumn::make('work_group8_id')
                ->requiredMapping()
                ->exampleHeader('Work Group Center 8')
                ->example('RMGCGABC8')
                ->label('Work Group Center 8'),
            ImportColumn::make('work_group9_id')
                ->requiredMapping()
                ->exampleHeader('Work Group Center 9')
                ->example('RMGCGABC9')
                ->label('Work Group Center 9'),
            ImportColumn::make('work_group10_id')
                ->requiredMapping()
                ->exampleHeader('Work Group Center 10')
                ->example('RMGCGABC10')
                ->label('Work Group Center 10'),
            ImportColumn::make('plant')
                ->requiredMapping()
                ->exampleHeader('Plant Name')
                ->example('Ransar Industries-I')
                ->label('Plant Name')
                ->relationship(resolveUsing:'name')
                ->rules(['required']),
        ];
    }

    public function resolveRecord(): ?Line
    {
        $warnMsg = [];

        $plant = Plant::where('name', $this->data['plant'])->first();
        if (!$plant) {
            throw new RowImportFailedException("Plant '{$this->data['plant']}' not found");
        }

        if (Str::length($this->data['name'] ?? '') <= 0) {
            throw new RowImportFailedException("Line name not found");
        }

        if (Str::length($this->data['type'] ?? '') <= 0) {
            throw new RowImportFailedException("Line type not found");
        }

        $noOfOps = (int) ($this->data['no_of_operation'] ?? 0);

        if (($noOfOps == null || $noOfOps == '' || !is_numeric($noOfOps)) && $noOfOps != 0) {
            throw new RowImportFailedException("'No of Operation' is required and must be a number $noOfOps");
        }

        if ($noOfOps > 10)
        {
            throw new RowImportFailedException("Invalid 'No Of Operation' value: {$noOfOps}, maximum allowed is 10");
        }

        // Validate required work groups
        $missingGroups = [];
        for ($i = 1; $i <= $noOfOps; $i++) {
            if (empty($this->data["work_group{$i}_id"])) {
                $missingGroups[] = "work_group{$i}_id";
            }
        }
        if (!empty($missingGroups)) {
            throw new RowImportFailedException(
                "Invalid data: Required work groups missing values in: " . implode(', ', $missingGroups)
            );
        }

        // Ensure no extra work groups are filled
        $invalidGroups = [];
        for ($i = $noOfOps + 1; $i <= 10; $i++) {
            if (!empty($this->data["work_group{$i}_id"])) {
                $invalidGroups[] = "work_group{$i}_id";
            }
        }
        if (!empty($invalidGroups)) {
            throw new RowImportFailedException(
                "Invalid data: Only first {$noOfOps} work groups should be filled, but values found in: " . implode(', ', $invalidGroups)
            );
        }

        for ($i = 1; $i <= 10; $i++) {
            $workGroupName = $this->data["work_group{$i}_id"] ?? null;
            if (!$workGroupName) {
                continue;
            }

            $workGroupRecord = WorkGroupMaster::where('name', $workGroupName)
                ->where('plant_id', $plant->id)
                ->first();

            if (!$workGroupRecord) {
                throw new RowImportFailedException("Work group '{$workGroupName}' not found in plant '{$this->data['plant']}'");
            }

            $existsInLines = Line::where('plant_id', $plant->id)
                ->where('name', '!=', $this->data['name'])
                ->where("work_group{$i}_id", $workGroupRecord->id)
                ->first();

            if ($existsInLines) {
                $warnMsg[] = "Work group '{$workGroupName}' is already assigned to another line in plant '{$this->data['plant']}'";
            }

            $this->data["work_group{$i}_id"] = $workGroupRecord->id;
        }

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

        Line::updateOrCreate(
            [
                'name' => $this->data['name'],
                'plant_id' => $plant->id
            ],
            [
                'type' => $this->data['type'],
                'no_of_operation' => $noOfOps,
                'work_group1_id'   => $this->data['work_group1_id'] ?? null,
                'work_group2_id'   => $this->data['work_group2_id'] ?? null,
                'work_group3_id'   => $this->data['work_group3_id'] ?? null,
                'work_group4_id'   => $this->data['work_group4_id'] ?? null,
                'work_group5_id'   => $this->data['work_group5_id'] ?? null,
                'work_group6_id'   => $this->data['work_group6_id'] ?? null,
                'work_group7_id'   => $this->data['work_group7_id'] ?? null,
                'work_group8_id'   => $this->data['work_group8_id'] ?? null,
                'work_group9_id'   => $this->data['work_group9_id'] ?? null,
                'work_group10_id'  => $this->data['work_group10_id'] ?? null,
            ]
        );

        return null;
    }

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