<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Date;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use League\Csv\Reader;
use App\Models\Categoria;
use App\Models\Caracteristica;
use App\Models\Producto;

class CanastaSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        $columnaTipo = 'Tipo';
        $columnaProducto = 'Producto';
        $columnaPrecio = 'Precio';
        $tipos = ['P','PTC','B'];

        $csv = Reader::createFromPath(resource_path('csv/productos.csv'), 'r');
        $csv->setDelimiter('|');
        $csv->setHeaderOffset(0);
        $records = $csv->getRecords();

        $productos = [];
        $caracteristicasAInsertar = [];
        $categoriaActual;
        foreach ($records as $i => $record) {
            $tipo = trim($record[$columnaTipo]);

            if (!in_array($tipo, $tipos)) {
                if (!Str::contains($tipo,'¿') && ($tipo != 'T')) {
                    $categoriaActual = Categoria::firstOrCreate(['nombre' => $tipo]);
                }
            } else {
                [$solidario, $nombre, $caracteristicas] = $this->parsearNombre($record[$columnaProducto]);
                
                $productos[] = [
                    'nombre'  => $nombre,
                    'precio' => $record[$columnaPrecio],
                    'solidario' => $solidario,
                    'bono' => $tipo == 'B',
                    'categoria_id' => $categoriaActual->id,
                    'created_at' => Date::now(),
                    'updated_at' => Date::now(),
                ];

                $caracteristicasAInsertar[] = [
                    'nombre' => $nombre,
                    'caracteristicas' => $caracteristicas
                ];
            }
        }
        
        foreach (array_chunk($productos,DatabaseSeeder::CHUNK_SIZE) as $chunk)
            DB::table('productos')->insert($chunk);

        $this->insertarCaracteristicas($caracteristicasAInsertar);
    }

    /**
     * Devuelve un array con datos parseados de $columnaProducto
     *
     * @return array{solidario: bool, nombre: string, caracteristicas: array(Caracteristica)} 
     */
    private function parsearNombre($columnaProducto): array {
        $solidario = Str::contains($columnaProducto, '*');
        $nombre = Str::replace('*','',$columnaProducto);

        $caracteristicas = [];
        if (Str::contains($nombre, 'S-G'))
            $caracteristicas[] = Caracteristica::where('codigo','S-G')->first()->id;
        if (Str::contains($nombre, 'S-A'))
            $caracteristicas[] = Caracteristica::where('codigo','S-A')->first()->id;
        if (Str::contains($nombre, 'S-S'))
            $caracteristicas[] = Caracteristica::where('codigo','S-S')->first()->id;
        if (Str::contains($nombre, 'S-P-A'))
            $caracteristicas[] = Caracteristica::where('codigo','S-P-A')->first()->id;

        if ($caracteristicas) {
            $nombre = Str::replaceMatches('/\(S\-.*\)/', '', $nombre);
        }

        return [$solidario, trim($nombre), $caracteristicas];
    }

    private function insertarCaracteristicas($caracteristicasAInsertar) : void {
        foreach ($caracteristicasAInsertar as $codigo => $item) {
            $nombre = $item['nombre'];
            $match = Producto::where('nombre',$nombre)->first();
            if ($match) {
                foreach ($item['caracteristicas'] as $codigo => $caracteristica) {
                    $match->caracteristicas()->attach($caracteristica);
                }
            }
        }
    }
}