<?php

namespace App\Services\ImportExport\Handlers;

use App\Models\InventoryItem;

class InventoryHandler extends AbstractModuleHandler
{
    public function key(): string
    {
        return 'inventory';
    }

    public function label(): string
    {
        return 'Inventory';
    }

    public function permissionModule(): string
    {
        return 'extras';
    }

    public function supportsImport(): bool
    {
        return true;
    }

    public function importColumns(): array
    {
        return [
            ['key' => 'sku', 'label' => 'SKU', 'required' => false, 'type' => 'string', 'example' => 'SKU-001', 'notes' => 'Unique stock code; auto-generated if blank'],
            ['key' => 'name', 'label' => 'Item Name', 'required' => true, 'type' => 'string', 'example' => 'A4 Exercise Book', 'notes' => 'Required'],
            ['key' => 'category', 'label' => 'Category', 'required' => false, 'type' => 'string', 'example' => 'Stationery', 'notes' => 'Optional'],
            ['key' => 'unit', 'label' => 'Unit', 'required' => false, 'type' => 'string', 'example' => 'each', 'notes' => 'Unit of measure'],
            ['key' => 'quantity_on_hand', 'label' => 'Quantity On Hand', 'required' => false, 'type' => 'integer', 'example' => '100', 'notes' => 'Must be zero or positive'],
            ['key' => 'reorder_level', 'label' => 'Reorder Level', 'required' => false, 'type' => 'integer', 'example' => '20', 'notes' => 'Minimum stock level'],
            ['key' => 'unit_cost', 'label' => 'Unit Cost', 'required' => false, 'type' => 'decimal', 'example' => '5.50', 'notes' => 'Cost per unit'],
            ['key' => 'location', 'label' => 'Location', 'required' => false, 'type' => 'string', 'example' => 'Store Room A', 'notes' => 'Storage location'],
            ['key' => 'status', 'label' => 'Status', 'required' => false, 'type' => 'string', 'example' => 'active', 'notes' => 'active or inactive'],
        ];
    }

    public function exportData(array $filters): array
    {
        $items = InventoryItem::query()->orderBy('name')->get();

        return [
            'title' => 'Inventory Export',
            'sheet_name' => 'Inventory',
            'headings' => ['SKU', 'Name', 'Category', 'Unit', 'Qty On Hand', 'Reorder Level', 'Unit Cost', 'Location', 'Status'],
            'rows' => $items->map(fn (InventoryItem $i) => [
                $i->sku,
                $i->name,
                $i->category,
                $i->unit,
                $i->quantity_on_hand,
                $i->reorder_level,
                number_format((float) $i->unit_cost, 2, '.', ''),
                $i->location,
                $i->status,
            ])->all(),
            'filters' => $this->filterSummary($filters),
            'totals' => ['Items' => $items->count(), 'Total Qty' => $items->sum('quantity_on_hand')],
        ];
    }

    public function validateImportRow(array $row, int $rowNumber): array
    {
        $errors = array_merge(
            $this->validateRequired($row, $rowNumber, ['name']),
            $this->validateDecimal($row, $rowNumber, 'unit_cost'),
        );

        foreach (['quantity_on_hand', 'reorder_level'] as $field) {
            if (filled($row[$field] ?? null) && (! is_numeric($row[$field]) || (int) $row[$field] < 0)) {
                $errors[] = [
                    'column' => $field,
                    'value' => $row[$field],
                    'message' => "Row {$rowNumber}: {$field} must be a non-negative integer.",
                    'suggestion' => 'Enter 0 or a positive whole number.',
                ];
            }
        }

        return $errors;
    }

    public function importRow(array $row): array
    {
        $attrs = [
            'name' => $row['name'],
            'category' => $row['category'] ?? null,
            'unit' => $row['unit'] ?? 'each',
            'quantity_on_hand' => (int) ($row['quantity_on_hand'] ?? 0),
            'reorder_level' => (int) ($row['reorder_level'] ?? 0),
            'unit_cost' => filled($row['unit_cost'] ?? null) ? $row['unit_cost'] : 0,
            'location' => $row['location'] ?? null,
            'status' => $row['status'] ?? 'active',
        ];

        if (filled($row['sku'] ?? null)) {
            $item = InventoryItem::query()->updateOrCreate(['sku' => $row['sku']], $attrs);

            return ['action' => $item->wasRecentlyCreated ? 'create' : 'updated', 'message' => null];
        }

        $sku = 'SKU-'.str_pad((string) (InventoryItem::query()->max('id') + 1), 5, '0', STR_PAD_LEFT);
        InventoryItem::query()->create(array_merge($attrs, ['sku' => $sku]));

        return ['action' => 'create', 'message' => null];
    }
}
