<?php

namespace App\Http\Controllers;

use App\Models\GrupoSuministros;
use App\Models\AvanceModulos;
use Illuminate\Http\Request;

class GrupoSuministrosController extends Controller
{
    private $apiKey;

    function __construct() {
        $apiController = new ApiController();

        $this->apiKey = $apiController->getApiKey()["key"];
    }

    public function crearGrupoSuministros(Request $request) {
        $id = new \stdClass();

        \DB::transaction(function() use(&$id, $request) {
            $grupoSuminsitros = GrupoSuministros::on('costos_principal');

            $id = $grupoSuminsitros->create(
                [
                    "con_fk_id" => $request->input("con_fk_id"),
                    "ins_fk_id" => $request->input("ins_fk_id"),
                    "grs_ano" => $request->input("grs_ano"),
                    "grs_codigo" => $request->input("grs_codigo"),
                    "grs_nombre" => $request->input("grs_nombre")
                ]
            );

            $this->verificarAvance($request->input("con_fk_id"),
                                   $request->input("ins_fk_id"),
                                   $request->input("grs_ano"));
        });

        return array("response" => $id->grs_pk_id);
    }

    public function actualizarGrupoSuministros(Request $request) {
        GrupoSuministros::on('costos_principal')
                        ->where("con_fk_id", $request->input("con_fk_id"))
                        ->where("ins_fk_id", $request->input("ins_fk_id"))
                        ->where("grs_ano", $request->input("grs_ano"))
                        ->where("grs_codigo", $request->input("grs_codigo"))
        ->update(
            [
                "grs_nombre" => $request->input("grs_nombre")
            ]
        );
    }

    public function borrarGrupoSuministros(Request $request) {
        \DB::transaction(function() use(&$id, $request) {
            GrupoSuministros::on('costos_principal')
                            ->where("grs_pk_id", $request->input("grs_pk_id"))
                            ->delete();
                            
            $this->verificarAvance($request->input("con_fk_id"),
                                   $request->input("ins_fk_id"),
                                   $request->input("grs_ano"));
        });
    }

    public function getGrupoSuministros(Request $request) {
        return GrupoSuministros::on('costos_principal')
                               ->where('con_fk_id', $request->input('con_fk_id'))
                               ->where('ins_fk_id', $request->input('ins_fk_id'))
                               ->where('grs_ano', $request->input('grs_ano'))
                               ->orderBy('grs_codigo')
                               ->orderBy('grs_nombre')
                               ->get()->toArray();

    }

    public function getGrupoSuministrosCsv(Request $request) {
        return GrupoSuministros::on('costos_principal')
                               ->select('grs_codigo', 'grs_nombre')
                               ->where('con_fk_id', $request->input('con_fk_id'))
                               ->where('ins_fk_id', $request->input('ins_fk_id'))
                               ->where('grs_ano', $request->input('grs_ano'))
                               ->orderBy('grs_codigo')
                               ->orderBy('grs_nombre')
                               ->get()->toArray();

    }

    public function getGrupoSuministrosEspecifico(Request $request) {
        return GrupoSuministros::on('costos_principal')
                               ->where('con_fk_id', $request->input('con_fk_id'))
                               ->where('ins_fk_id', $request->input('ins_fk_id'))
                               ->where('grs_ano', $request->input('grs_ano'))
                               ->where('grs_codigo', $request->input('grs_codigo'))
                               ->get()->toArray();

    }

    public function cargarArchivoGrupoSuministros(Request $request) {
        $apiKey = $request->apiKey;

        if ($apiKey === $this->apiKey) {
            $rutaDelArchivo = $request->grupoSuministros->path();
            $delimitador = $request->delimitador;
            $archivo = fopen($rutaDelArchivo, 'r');
            $grupoSuministros = array();
            $primeraLinea = true;

            // Extraer cada línea del archivo CSV y convertirlo en un arreglo
            while($linea = fgetcsv($archivo, 1000, $delimitador)) {
                if (!$primeraLinea) {
                    $registro = $linea;
                    array_push($grupoSuministros, $registro);
                } else {
                    $primeraLinea = false;
                }
            }

            fclose($archivo);

            return $this->procesarArchivoGrupoSuministros($grupoSuministros,
                                                          $request->con_fk_id,
                                                          $request->ins_fk_id,
                                                          $request->grs_ano);
        } else {
            throw new \Exception('Imposible completar la petición.');
        }
    }

    private function procesarArchivoGrupoSuministros($grupoSuministros, $con_fk_id, $ins_fk_id, $grs_ano) {
        $resultados = new \stdClass();
        $resultados->errores = "";

        \DB::transaction(function() use(&$resultados, $grupoSuministros, $con_fk_id, $ins_fk_id, $grs_ano) {
            if (count($grupoSuministros) === 0) {
                $resultados->correcto = false;
                $resultados->errores = 'El archivo está vacío. ';
                return json_encode($resultados);
            } else if (count($grupoSuministros[0]) !== 2) {
                $resultados->correcto = false;
                $resultados->errores = 'La cantidad de columnas no corresponde. ';
                return json_encode($resultados);
            } else {
                $grupoSuministrosBd = GrupoSuministros::on('costos_principal')
                                                    ->where('con_fk_id', $con_fk_id)
                                                    ->where('ins_fk_id', $ins_fk_id)
                                                    ->where('grs_ano', $grs_ano)
                                                    ->get()->toArray();

                $grupoSuministrosExistentes = [];

                // Crear las relaciones existentes en la base de datos
                foreach ($grupoSuministrosBd as $grsDb) {
                    $grupoSuministrosExistentes[$grsDb['grs_codigo']] = $grsDb['grs_nombre'];
                }

                // Errores de los centros de utilidad
                $registrosProcesados = 0;
                $descripcionesLargas = false;
                $camposVacios = false;

                // Revisar el archivo respecto a las relaciones existentes
                foreach($grupoSuministros as $grsCsv) {
                    $codigo = strtoupper(utf8_encode(trim($grsCsv[0])));
                    $nombre = utf8_encode(trim($grsCsv[1]));

                    // Campos vacios
                    if ($codigo != "" && $nombre != "") {
                        // Descripcion largas
                        if (strlen($codigo) <= 10 && strlen($nombre) <= 80) {
                            // Existe el grupo de suministros
                            if (isset($grupoSuministrosExistentes[$codigo])) {
                                // Actualizar si la descripcion es diferente
                                if ($grupoSuministrosExistentes[$codigo] != $nombre) {
                                    GrupoSuministros::on('costos_principal')
                                                    ->where("con_fk_id", $con_fk_id)
                                                    ->where("ins_fk_id", $ins_fk_id)
                                                    ->where("grs_ano", $grs_ano)
                                                    ->where("grs_codigo", $codigo)
                                    ->update(
                                        [
                                            "grs_nombre" => $nombre
                                        ]
                                    );

                                    $registrosProcesados++;
                                } else {
                                    $registrosProcesados++;
                                }
                            } else { // Crear el grupo de suministros
                                $grupoSuministrosNuevo = GrupoSuministros::on('costos_principal');

                                $id = $grupoSuministrosNuevo->create(
                                    [
                                        "con_fk_id" => $con_fk_id,
                                        "ins_fk_id" => $ins_fk_id,
                                        "grs_ano" => $grs_ano,
                                        "grs_codigo" => $codigo,
                                        "grs_nombre" => $nombre
                                    ]
                                );

                                $registrosProcesados++;

                                $grupoSuministrosExistentes[$codigo] = $nombre;
                            }
                        } else {
                            $descripcionesLargas = true;
                        }
                    } else {
                        $camposVacios = true;
                    }
                }

                // Descripciones largas
                if ($descripcionesLargas) {
                    if ($resultados->errores !== "") {
                        $resultados->errores .= "-  ";
                    }

                    $resultados->errores .= "Hay descripciones con longitudes incorrectas. Son 10 caracteres para el código y
                                             80 para el nombre.";
                }

                // Campos vacios
                if ($camposVacios) {
                    if ($resultados->errores !== "") {
                        $resultados->errores .= "-  ";
                    }

                    $resultados->errores .= "Hay campos vacíos";
                }

                if (!$descripcionesLargas && !$camposVacios) {
                    $resultados->correcto = true;
                } else {
                    $resultados->correcto = false;
                }

                $resultados->registros = $registrosProcesados;
            }

            $this->verificarAvance($con_fk_id, $ins_fk_id, $grs_ano);
        });

        return json_encode($resultados);
    }

    public function verificarAvance($contrato, $institucion, $ano) {
        // Verificar si existe registro del avance
        $conteo = AvanceModulos::on('costos_principal')
                               ->where('con_fk_id', $contrato)
                               ->where('ins_fk_id', $institucion)
                               ->where('avm_ano', $ano)
                               ->whereNull('avm_mes')
                               ->count();

        // Verificar el avance del modulo
        $grs = GrupoSuministros::on('costos_principal')
                               ->where('con_fk_id', $contrato)
                               ->where('ins_fk_id', $institucion)
                               ->where('grs_ano', $ano)
                               ->count();

        if ($conteo > 0) {
            if ($grs > 0) {
                AvanceModulos::on('costos_principal')
                                ->where('con_fk_id', $contrato)
                                ->where('ins_fk_id', $institucion)
                                ->where('avm_ano', $ano)
                                ->where('avm_mes', null)
                ->update(
                    [
                        "avm_gr_suministros" => true
                    ]
                );
            } else {
               AvanceModulos::on('costos_principal')
                            ->where('con_fk_id', $contrato)
                            ->where('ins_fk_id', $institucion)
                            ->where('avm_ano', $ano)
                            ->where('avm_mes', null)
                ->update(
                    [
                        "avm_gr_suministros" => false
                    ]
                ); 
            }
        } else {
            AvanceModulos::on('costos_principal')
            ->create(
                [
                    "con_fk_id" => $contrato,
                    "ins_fk_id" => $institucion,
                    "avm_ano" => $ano,
                    "avm_mes" => null,
                    "avm_gr_suministros" => true
                ]
            );
        }            
    }
}
