<?php

namespace App\Http\Controllers;

use App\Models\DetallePobPrograma;
use App\Models\Programas;
use App\Models\EstadiosProgramas;
use App\Models\SedesProgramas;
use Illuminate\Http\Request;

class DetallePobProgramaController extends Controller
{
    private $apiKey;

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

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

    public function getDetallePobPrograma(Request $request) {
        return DetallePobPrograma::on('costos_principal')
                                ->selectRaw('prg_codigo, prg_descripcion, coe_numero_contrato, coe_nombre_eps, sed_nombre_sede, esp_codigo, esp_descripcion,
                                             dpp_poblacion, dpp_valor_unitario')
                                ->join('programas', 'prg_pk_id', 'detalle_pob_programa.prg_fk_id')
                                ->join('contratos_eps', 'coe_pk_id', 'coe_fk_id')
                                ->join('estadios_programas', 'esp_pk_id', 'esp_fk_id')
                                ->join('sedes', function($join) {
                                    $join->on('sedes.con_fk_id', 'detalle_pob_programa.con_fk_id');
                                    $join->on('sed_pk_id', 'sed_fk_id');
                                })
                                ->where('detalle_pob_programa.con_fk_id', $request->input('con_fk_id'))
                                ->where('detalle_pob_programa.ins_fk_id', $request->input('ins_fk_id'))
                                ->where('dpp_ano', $request->input('dpp_ano'))
                                ->where('dpp_mes', $request->input('dpp_mes'))
                                ->get()->toArray();

    }

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

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

            fclose($archivo);

            return $this->procesarArchivoDetallePobPrograma($detallePobPrograma,
                                                            $request->con_fk_id,
                                                            $request->ins_fk_id,
                                                            $request->dpp_ano,
                                                            $request->dpp_mes);
        } else {
            throw new \Exception('Imposible completar la petición.');
        }
    }

    private function procesarArchivoDetallePobPrograma($detallePobPrograma, $con_fk_id, $ins_fk_id, $dpp_ano, $dpp_mes) {
        $resultados = new \stdClass();
        $resultados->errores = "";

        \DB::transaction(function() use(&$resultados, $detallePobPrograma, $con_fk_id, $ins_fk_id, $dpp_ano, $dpp_mes) {
            if (count($detallePobPrograma) === 0) {
                $resultados->correcto = false;
                $resultados->errores = 'El archivo está vacío. ';
                return json_encode($resultados);
            } else if (count($detallePobPrograma[0]) !== 6) {
                $resultados->correcto = false;
                $resultados->errores = 'La cantidad de columnas no corresponde. ';
                return json_encode($resultados);
            } else {
                // Borrar la información anterior
                DetallePobPrograma::on('costos_principal')
                                  ->where('con_fk_id', $con_fk_id)
                                  ->where('ins_fk_id', $ins_fk_id)
                                  ->where('dpp_ano', $dpp_ano)
                                  ->where('dpp_mes', $dpp_mes)
                                  ->delete();

                // Parametros de la base de datos
                $programasBd = Programas::on('costos_principal')
                                        ->where('con_fk_id', $con_fk_id)
                                        ->where('ins_fk_id', $ins_fk_id)
                                        ->where('prg_ano', $dpp_ano)
                                        ->get()->toArray();

                $estadiosBd = EstadiosProgramas::on('costos_principal')
                                               ->where('con_fk_id', $con_fk_id)
                                               ->where('ins_fk_id', $ins_fk_id)
                                               ->where('esp_ano', $dpp_ano)
                                               ->get()->toArray();

                $sedesProgramasBd = SedesProgramas::on('costos_principal')
                                                  ->where('con_fk_id', $con_fk_id)
                                                  ->where('ins_fk_id', $ins_fk_id)
                                                  ->where('sep_ano', $dpp_ano)
                                                  ->get()->toArray();

                $detallePobProgramaExistente = [];
                $programasExistentes = [];
                $estadiosExistentes = [];
                $programasSedesExistentes = [];

                foreach ($programasBd as $prgDb) {
                    $programasExistentes[$prgDb['prg_codigo']][$prgDb['coe_fk_id']] = $prgDb['prg_pk_id'];
                }

                foreach ($estadiosBd as $espDb) {
                    $estadiosExistentes[$espDb['prg_fk_id']][$espDb['esp_codigo']] = $espDb['esp_pk_id'];
                }

                foreach ($sedesProgramasBd as $sepDb) {
                    $programasSedesExistentes[$sepDb['prg_fk_id']][$sepDb['sed_fk_id']] = $sepDb['sep_pk_id'];
                }

                // Errores de los centros de utilidad
                $camposVacios = false;
                $valoresIncorrectos = false;
                $programasInexistentes = "";
                $relProgramaSedeInexistentes = "";
                $estadiosInexistentes = "";
                $registrosProcesados = 0;

                // Revisar el archivo respecto a las relaciones existentes
                foreach($detallePobPrograma as $dppCsv) {
                    $programa = trim($dppCsv[0]);
                    $contrato = trim($dppCsv[1]);
                    $sede = trim($dppCsv[2]);
                    $estadio = trim($dppCsv[3]);
                    $poblacion = trim($dppCsv[4]);
                    $valorUnitario = trim($dppCsv[5]);

                    // Campos vacios
                    if ($programa != "" && $contrato != "" && $sede != "" && $estadio != "" && $poblacion != "" && $valorUnitario != "") {
                        // Numeros incorrectos
                        if (is_numeric($poblacion) && is_numeric($valorUnitario) && intval($poblacion) > 0 && intval($valorUnitario) >= 0) {
                            // Existe el programa
                            if (isset($programasExistentes[$programa][$contrato])) {
                                $idPrg = $programasExistentes[$programa][$contrato];

                                // Existe la relación entre sede-programa
                                if (isset($programasSedesExistentes[$idPrg][$sede])) {
                                    // Existe el estadío
                                    if (isset($estadiosExistentes[$idPrg][$estadio])) {
                                        $idEsp = $estadiosExistentes[$idPrg][$estadio];

                                        // Actualizar si existe
                                        if (isset($detallePobProgramaExistente[$idPrg][$sede][$estadio])) {
                                            $id = $detallePobProgramaExistente[$idPrg][$sede][$estadio];

                                            DetallePobPrograma::on('costos_principal')->where('dpp_pk_id', $id)
                                            ->update(
                                                [
                                                    "dpp_poblacion" => $poblacion,
                                                    "dpp_valor_unitario" => $valorUnitario
                                                ]
                                            );
                                        } else {
                                            $id = DetallePobPrograma::on('costos_principal')->create(
                                                [
                                                    "con_fk_id" => $con_fk_id,
                                                    "ins_fk_id" => $ins_fk_id,
                                                    "dpp_ano" => $dpp_ano,
                                                    "dpp_mes" => $dpp_mes,
                                                    "sed_fk_id" => $sede,
                                                    "prg_fk_id" => $idPrg,
                                                    "esp_fk_id" => $idEsp,
                                                    "dpp_poblacion" => $poblacion,
                                                    "dpp_valor_unitario" => $valorUnitario
                                                ]
                                            )->dpp_pk_id;

                                            $detallePobProgramaExistente[$idPrg][$sede][$estadio] = $id;
                                        }

                                        $registrosProcesados++;
                                    } else {
                                        $estadiosInexistentes .= $estadio.' en '.$programa.", ";
                                    }
                                } else {
                                    $relProgramaSedeInexistentes .= $sede.' en '.$programa.", ";
                                }
                            } else {
                                $programasInexistentes .= $programa." - ".$contrato.", ";
                            }
                        } else {
                            $valoresIncorrectos = true;
                        }
                    } else {
                        $camposVacios = true;
                    }
                }

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

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

                // Valores numericos incorrectos
                    if ($valoresIncorrectos) {
                    if ($resultados->errores !== "") {
                        $resultados->errores .= " -  ";
                    }

                    $resultados->errores .= "Hay valores numéricos incorrectos. La población y el valor unitario no pueden ser menores a cero.";
                }

                // Errores de programas
                if ($programasInexistentes !== "") {
                    $programasInexistentes[strlen($programasInexistentes) - 1] = " ";
                    $programasInexistentes[strlen($programasInexistentes) - 2] = " ";
                    $programasInexistentes = "No existen los siguientes programa-contrato: ".$programasInexistentes;

                    if ($resultados->errores !== "") {
                    $resultados->errores .= " -  ";
                    }

                    $resultados->errores .= $programasInexistentes;
                }

                // Errores de rel sede - programa
                if ($relProgramaSedeInexistentes !== "") {
                    $relProgramaSedeInexistentes[strlen($relProgramaSedeInexistentes) - 1] = " ";
                    $relProgramaSedeInexistentes[strlen($relProgramaSedeInexistentes) - 2] = " ";
                    $relProgramaSedeInexistentes = "No existen las siguientes relaciones entre sede-programa: ".$relProgramaSedeInexistentes;

                    if ($resultados->errores !== "") {
                    $resultados->errores .= " -  ";
                    }

                    $resultados->errores .= $relProgramaSedeInexistentes;
                }

                // Errores de estadíos
                if ($estadiosInexistentes !== "") {
                    $estadiosInexistentes[strlen($estadiosInexistentes) - 1] = " ";
                    $estadiosInexistentes[strlen($estadiosInexistentes) - 2] = " ";
                    $estadiosInexistentes = "No existen los siguientes estadíos en el programa: ".$estadiosInexistentes;

                    if ($resultados->errores !== "") {
                    $resultados->errores .= " -  ";
                    }

                    $resultados->errores .= $estadiosInexistentes;
                }

                if (!$camposVacios && !$valoresIncorrectos && $programasInexistentes == "" && $relProgramaSedeInexistentes == "" && $estadiosInexistentes == "") {
                    $resultados->correcto = true;
                } else {
                    $resultados->correcto = false;
                }

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

        return json_encode($resultados);
    }
}
