<?php

namespace App\Http\Controllers;

use App\Models\SuministrosCentroCosto;
use App\Models\CentrosCosto;
use App\Models\GrupoSuministros;
use App\Models\TipoRecurso;
use App\Models\CaracterRecurso;
use Illuminate\Http\Request;

class SuministrosCentroCostoController extends Controller
{
    private $apiKey;

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

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

    public function getSuministrosCentroCosto(Request $request) {
        return SuministrosCentroCosto::on('costos_principal')
                                     ->where('con_fk_id', $request->input("con_fk_id"))
                                     ->where('ins_fk_id', $request->input("ins_fk_id"))
                                     ->where('scc_ano', $request->input("scc_ano"))
                                     ->get()->toArray();

    }

    public function getSuministroCentroCostoEspecifico(Request $request) {
        return SuministrosCentroCosto::on('costos_principal')
                                     ->where('scc_pk_id', $request->input('scc_pk_id'))
                                     ->get()->toArray();

    }

    public function crearSuministroCentroCosto(Request $request) {
        $suministroCc = SuministrosCentroCosto::on('costos_principal');

        $id = $suministroCc->create(
            [
                "con_fk_id" => $request->input("con_fk_id"),
                "ins_fk_id" => $request->input("ins_fk_id"),
                "scc_ano" => $request->input("scc_ano"),
                "cco_fk_id" => $request->input("cco_fk_id"),
                "grs_fk_id" => $request->input("grs_fk_id"),
                "tre_fk_id" => $request->input("tre_fk_id"),
                "cre_fk_id" => $request->input("cre_fk_id")
            ]
        );

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

    public function actualizarSuministroCentroCosto(Request $request) {
        SuministrosCentroCosto::on('costos_principal')->where("scc_pk_id", $request->input("scc_pk_id"))
        ->update(
            [
                "tre_fk_id" => $request->input("tre_fk_id"),
                "cre_fk_id" => $request->input("cre_fk_id")
            ]
        );
    }

    public function borrarSuministroCentroCosto(Request $request) {
        SuministrosCentroCosto::on('costos_principal')
                              ->where("scc_pk_id", $request->input("scc_pk_id"))
                              ->delete();
    }

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

        if ($apiKey === $this->apiKey) {
            $rutaDelArchivo = $request->suministrosCentroCosto->path();
            $delimitador = $request->delimitador;
            $archivo = fopen($rutaDelArchivo, 'r');
            $suministrosCentroCosto = 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($suministrosCentroCosto, $registro);
                } else {
                    $primeraLinea = false;
                }
            }

            fclose($archivo);

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

    private function procesarArchivoSuministrosCentroCosto($suministrosCentroCosto, $con_fk_id, $ins_fk_id, $scc_ano) {
        $resultados = new \stdClass();
        $resultados->errores = "";

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

                $grupoSuministrosBd = GrupoSuministros::on('costos_principal')
                                                      ->where('con_fk_id', $con_fk_id)
                                                      ->where('ins_fk_id', $ins_fk_id)
                                                      ->where('grs_ano', $scc_ano)
                                                      ->get()->toArray();

                $tiposRecursoBd = TipoRecurso::on('costos_principal')->get()->toArray();
                $caracteresRecursoBd = CaracterRecurso::on('costos_principal')->get()->toArray();

                $suministrosCentroCostBd = SuministrosCentroCosto::on('costos_principal')
                                                                 ->join('centros_costo', 'cco_pk_id', 'cco_fk_id')
                                                                 ->join('grupo_suministros', 'grs_pk_id', 'grs_fk_id')
                                                                 ->where('suministros_centro_costo.con_fk_id', $con_fk_id)
                                                                 ->where('suministros_centro_costo.ins_fk_id', $ins_fk_id)
                                                                 ->where('scc_ano', $scc_ano)
                                                                 ->get()->toArray();

                $centrosCostoExistentes = [];
                $gruposSuministrosExistentes = [];
                $tiposRecursoExistentes = [];
                $caracteresRecursoExistentes = [];
                $suministrosCentroCostoExistentes = [];

                // Crear las relaciones existentes en la base de datos
                foreach ($centrosCostoBd as $ccoDb) {
                    $centrosCostoExistentes[$ccoDb['cco_cod_homologado']] = $ccoDb['cco_pk_id'];
                }

                foreach ($grupoSuministrosBd as $grsDb) {
                    $gruposSuministrosExistentes[$grsDb['grs_codigo']] = $grsDb['grs_pk_id'];
                }

                foreach ($tiposRecursoBd as $treDb) {
                    $tiposRecursoExistentes[$treDb['tre_pk_id']] = $treDb['tre_descripcion'];
                }

                foreach ($caracteresRecursoBd as $creDb) {
                    $caracteresRecursoExistentes[$creDb['cre_pk_id']] = $creDb['cre_descripcion'];
                }

                foreach ($suministrosCentroCostBd as $sccDb) {
                    $suministrosCentroCostoExistentes[$sccDb['cco_cod_homologado']][$sccDb['grs_codigo']] = new \stdClass();

                    $suministrosCentroCostoExistentes[$sccDb['cco_cod_homologado']][$sccDb['grs_codigo']]->tre_fk_id = $sccDb['tre_fk_id'];
                    $suministrosCentroCostoExistentes[$sccDb['cco_cod_homologado']][$sccDb['grs_codigo']]->cre_fk_id = $sccDb['cre_fk_id'];
                }

                // Variables de control
                $registrosProcesados = 0;
                $centrosCostoInexistentes = "";
                $gruposSuministrosInexistentes = "";
                $tiposRecursoInexistentes = "";
                $caracteresRecursoInexistentes = "";
                $camposVacios = false;

                // Revisar el archivo respecto a las relaciones existentes
                foreach($suministrosCentroCosto as $sccCsv) {
                    $centroCosto = strtoupper(utf8_encode(trim($sccCsv[0])));
                    $grupoSuministros = strtoupper(utf8_encode(trim($sccCsv[1])));
                    $tipoRecurso = utf8_encode(trim($sccCsv[2]));
                    $caracterRecurso = utf8_encode(trim($sccCsv[3]));

                    // Campos vacios
                    if ($centroCosto != "" && $grupoSuministros != "" && $tipoRecurso != "" && $caracterRecurso != "") {
                        // Existe el centro de costo
                        if (isset($centrosCostoExistentes[$centroCosto])) {
                            // Existe el suministro
                            if (isset($gruposSuministrosExistentes[$grupoSuministros])) {
                                // Existe el tipo de recurso
                                if (isset($tiposRecursoExistentes[$tipoRecurso])) {
                                    // Existe el caractr de recurso
                                    if (isset($caracteresRecursoExistentes[$caracterRecurso])) {
                                        if (isset($suministrosCentroCostoExistentes[$centroCosto][$grupoSuministros])) {
                                            // Actualizar si hay diferencias
                                            if ($suministrosCentroCostoExistentes[$centroCosto][$grupoSuministros]->tre_fk_id != $tipoRecurso ||
                                                $suministrosCentroCostoExistentes[$centroCosto][$grupoSuministros]->cre_fk_id != $caracterRecurso) {
                                                SuministrosCentroCosto::on('costos_principal')
                                                                      ->where("con_fk_id", $con_fk_id)
                                                                      ->where("ins_fk_id", $ins_fk_id)
                                                                      ->where("scc_ano", $scc_ano)
                                                                      ->where("cco_fk_id", $centrosCostoExistentes[$centroCosto])
                                                                      ->where("grs_fk_id", $gruposSuministrosExistentes[$grupoSuministros])
                                                ->update(
                                                    [
                                                        "tre_fk_id" => $tipoRecurso,
                                                        "cre_fk_id" => $caracterRecurso
                                                    ]
                                                );

                                                $registrosProcesados++;
                                            } else {
                                                $registrosProcesados++;
                                            }
                                        } else { // Crear el suministro por centro de costo
                                            $suministrosCentroCostoNuevo = SuministrosCentroCosto::on('costos_principal');

                                            $id = $suministrosCentroCostoNuevo->create(
                                                [
                                                    "con_fk_id" => $con_fk_id,
                                                    "ins_fk_id" => $ins_fk_id,
                                                    "scc_ano" => $scc_ano,
                                                    "cco_fk_id" => $centrosCostoExistentes[$centroCosto],
                                                    "grs_fk_id" => $gruposSuministrosExistentes[$grupoSuministros],
                                                    "tre_fk_id" => $tipoRecurso,
                                                    "cre_fk_id" => $caracterRecurso
                                                ]
                                            );

                                            $registrosProcesados++;

                                            $suministrosCentroCostoExistentes[$centroCosto][$grupoSuministros] = new \stdClass();

                                            $suministrosCentroCostoExistentes[$centroCosto][$grupoSuministros]->tre_fk_id = $tipoRecurso;
                                            $suministrosCentroCostoExistentes[$centroCosto][$grupoSuministros]->cre_fk_id = $caracterRecurso;
                                        }
                                    } else {
                                        $caracteresRecursoInexistentes .= $caracterRecurso.", ";    
                                    }
                                } else {
                                    $tiposRecursoInexistentes .= $tipoRecurso.", ";
                                }
                            } else {
                                $gruposSuministrosInexistentes .= $grupoSuministros.", "; 
                            }
                        } else {
                            $centrosCostoInexistentes .= $centroCosto.", ";
                        }
                    } else {
                        $camposVacios = true;
                    }
                }

                // Errores de centros de costos
                if ($centrosCostoInexistentes !== "") {
                    $centrosCostoInexistentes[strlen($centrosCostoInexistentes) - 1] = " ";
                    $centrosCostoInexistentes[strlen($centrosCostoInexistentes) - 2] = " ";
                    $centrosCostoInexistentes = "No existen los siguientes centros de costo: ".$centrosCostoInexistentes;

                    $resultados->errores = $centrosCostoInexistentes;
                }

                // Errores de grupo de suministros suministros
                if ($gruposSuministrosInexistentes !== "") {
                    $gruposSuministrosInexistentes[strlen($gruposSuministrosInexistentes) - 1] = " ";
                    $gruposSuministrosInexistentes[strlen($gruposSuministrosInexistentes) - 2] = " ";
                    $gruposSuministrosInexistentes = "No existen los siguientes grupos de suministros: ".$gruposSuministrosInexistentes;

                    $resultados->errores = $gruposSuministrosInexistentes;
                }

                // Errores de tipos de recurso
                if ($tiposRecursoInexistentes !== "") {
                    $tiposRecursoInexistentes[strlen($tiposRecursoInexistentes) - 1] = " ";
                    $tiposRecursoInexistentes[strlen($tiposRecursoInexistentes) - 2] = " ";
                    $tiposRecursoInexistentes = "No existen los siguientes tipos de recurso: ".$tiposRecursoInexistentes;

                    $resultados->errores = $tiposRecursoInexistentes;
                }

                // Errores de caracteres de recurso
                if ($caracteresRecursoInexistentes !== "") {
                    $caracteresRecursoInexistentes[strlen($caracteresRecursoInexistentes) - 1] = " ";
                    $caracteresRecursoInexistentes[strlen($caracteresRecursoInexistentes) - 2] = " ";
                    $caracteresRecursoInexistentes = "No existen los siguientes tipos de recurso: ".$caracteresRecursoInexistentes;

                    $resultados->errores = $caracteresRecursoInexistentes;
                }

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

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

                if (!$camposVacios && $centrosCostoInexistentes == "" && $gruposSuministrosInexistentes == "" && $tiposRecursoInexistentes == "" && $caracteresRecursoInexistentes == "") {
                    $resultados->correcto = true;
                } else {
                    $resultados->correcto = false;
                }

                $resultados->registros = $registrosProcesados;
            }
        });

        return json_encode($resultados);
    }
}
