<?php

namespace App\Imports;

use App\Models\RawMaterial;
use App\Services\Inventory\RawMaterialService;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithValidation;
use Maatwebsite\Excel\Concerns\SkipsOnFailure;
use Maatwebsite\Excel\Concerns\SkipsFailures;

class RawMaterialsImport implements ToCollection, WithHeadingRow, WithValidation, SkipsOnFailure
{
    use SkipsFailures;

    protected int $importedCount = 0;
    protected int $skippedCount = 0;
    protected array $errors = [];

    public function collection(Collection $rows)
    {
        $rawMaterialService = app(RawMaterialService::class);

        foreach ($rows as $index => $row) {
            $rowNumber = $index + 2; // Account for header row

            // Skip row if required field is missing
            if (empty($row['name']) && empty($row['rm_grade'])) {
                $this->skippedCount++;
                $this->errors[] = "Row {$rowNumber}: Missing name or RM grade";
                continue;
            }

            $name = trim($row['name'] ?? $row['rm_grade'] ?? '');
            $rmGrade = trim($row['rm_grade'] ?? '');

            // Skip if material with same name or grade already exists
            $existing = RawMaterial::where('name', $name)
                ->orWhere('rm_grade', $rmGrade)
                ->exists();

            if ($existing) {
                $this->skippedCount++;
                $this->errors[] = "Row {$rowNumber}: Material '{$name}' already exists";
                continue;
            }

            try {
                // Generate code if not provided
                $code = !empty($row['code'])
                    ? trim($row['code'])
                    : $rawMaterialService->generateCode();

                // Create new raw material with all fields
                RawMaterial::create([
                    'code' => $code,
                    'name' => $name,
                    'rm_grade' => $rmGrade,
                    'iso_specification' => $row['iso_specification'] ?? null,
                    'density' => $this->parseNumeric($row['density'] ?? null),
                    'raw_material_type' => $row['raw_material_type'] ?? $row['type'] ?? null,
                    'mechanical_properties' => $row['mechanical_properties'] ?? null,
                    'chemical_properties' => $row['chemical_properties'] ?? null,
                    'quantity' => $this->parseNumeric($row['quantity'] ?? 0),
                    'min_stock' => $this->parseNumeric($row['min_stock'] ?? 0),
                    'uom' => $row['uom'] ?? $row['unit'] ?? null,
                    'status' => $row['status'] ?? RawMaterial::STATUS_ACTIVE,
                    'created_by' => auth()->id(),
                ]);

                $this->importedCount++;
            } catch (\Exception $e) {
                $this->skippedCount++;
                $this->errors[] = "Row {$rowNumber}: " . $e->getMessage();
                Log::error("Raw Material Import Error at row {$rowNumber}", [
                    'name' => $name,
                    'error' => $e->getMessage(),
                ]);
            }
        }
    }

    /**
     * Validation rules for each row
     */
    public function rules(): array
    {
        return [
            'name' => 'nullable|string|max:255',
            'rm_grade' => 'nullable|string|max:255',
            'iso_specification' => 'nullable|string|max:255',
            'density' => 'nullable|numeric|min:0',
            'raw_material_type' => 'nullable|string|max:100',
            'quantity' => 'nullable|numeric|min:0',
            'min_stock' => 'nullable|numeric|min:0',
            'uom' => 'nullable|string|max:50',
        ];
    }

    /**
     * Parse numeric value, handling empty strings
     */
    protected function parseNumeric($value): ?float
    {
        if ($value === null || $value === '') {
            return null;
        }
        return is_numeric($value) ? (float) $value : null;
    }

    /**
     * Get imported count
     */
    public function getImportedCount(): int
    {
        return $this->importedCount;
    }

    /**
     * Get skipped count
     */
    public function getSkippedCount(): int
    {
        return $this->skippedCount;
    }

    /**
     * Get import errors
     */
    public function getErrors(): array
    {
        return $this->errors;
    }

    /**
     * Get import summary
     */
    public function getSummary(): array
    {
        return [
            'imported' => $this->importedCount,
            'skipped' => $this->skippedCount,
            'errors' => $this->errors,
        ];
    }
}
