<?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
    {
        $tipoColumn = 'Tipo';
        $productoColumn = 'Producto';
        $precioColumn = 'Precio';
        $tipos = ['P','PTC','B'];

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

        $productosToInsert = [];
        $caracteristicasToInsert = [];
        $currentCategoria;
        foreach ($records as $i => $record) {
            $tipo = trim($record[$tipoColumn]);

            if (!in_array($tipo, $tipos)) {
                if (!Str::contains($tipo,'¿') && ($tipo != 'T'))
                    $currentCategoria = Categoria::firstOrCreate(['name' => $tipo]);
            } else {
                [$solidario, $name, $caracteristicas] = $this->parseAndFormatName($record[$productoColumn]);
                
                $productosToInsert[] = [
                    'name'  => $name,
                    'price' => $record[$precioColumn],
                    'solidario' => $solidario,
                    'bono' => $tipo == 'B',
                    'categoria_id' => $currentCategoria->id,
                    'created_at' => Date::now(),
                    'updated_at' => Date::now(),
                ];

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

        $this->insertCaracteristicas($caracteristicasToInsert);
    }

    /**
     * Returns an array with data parsed from productoColumn.
     *
     * @return array{solidario: bool, name: string, caracteristicas: array(Caracteristica->id)} 
     */
    private function parseAndFormatName($productoColumn): array {
        $solidario = Str::contains($productoColumn, '*');
        $name = Str::replace('*','',$productoColumn);

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

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

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

    private function insertCaracteristicas($caracteristicasToInsert) : void {
        foreach ($caracteristicasToInsert as $key => $item) {
            $name = $item['name'];
            $match = Producto::where('name',$name)->first();
            if ($match) {
                foreach ($item['caracteristicas'] as $key => $caracteristica) {
                    DB::table('productos_caracteristicas')->insert([
                        'producto_id' => $match->id,
                        'caracteristica_id' => $caracteristica,
                    ]);
                }
            }
        }
    }
}