<?php

namespace App\Http\Controllers;

use App\Models\PaquetesActividades;
use App\Models\Paquetes;
use App\Models\CentrosCosto;
use App\Models\Actividades;
use Illuminate\Http\Request;

class PaquetesActividadesController extends Controller
{
    private $apiKey;

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

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

    public function getPaquetes(Request $request) {
        return Actividades::on('costos_principal')
                          ->where('con_fk_id', $request->input('con_fk_id'))
                          ->where('ins_fk_id', $request->input('ins_fk_id'))
                          ->where('act_ano', $request->input('paq_ano'))
                          ->where('act_paquete', true)
                          ->whereNotNull('act_desc_actividades')
                          ->get()->toArray();
    }

    public function getActividadesPaquete(Request $request) {
        return PaquetesActividades::on('costos_principal')
                                  ->join('centros_costo', 'cco_pk_id', 'cco_fk_id')
                                  ->leftJoin('actividades', 'act_pk_id', 'paq_actividad')
                                  ->leftJoin('suministros', 'sum_pk_id', 'paq_suministro')
                                  ->where('paquetes_actividades.con_fk_id', $request->input('con_fk_id'))
                                  ->where('paquetes_actividades.ins_fk_id', $request->input('ins_fk_id'))
                                  ->where('paq_ano', $request->input('paq_ano'))
                                  ->where('paq_paquete', $request->input('paq_paquete'))
                                  ->get()->toArray();
    }

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

        \DB::transaction(function() use(&$id, $request) {
            $con_fk_id = $request->input('con_fk_id');
            $ins_fk_id = $request->input('ins_fk_id');
            $paq_ano = $request->input('paq_ano');
            $paquete = $request->input('paq_paquete');
            $act_desc_actividades = $request->input('act_desc_actividades');
            $actividadesSuministros = json_decode($request->input('actividades'));

            Actividades::on('costos_principal')->where('act_pk_id', $paquete)->update(["act_desc_actividades" => $act_desc_actividades]);

            foreach($actividadesSuministros as $act) {
                $tipo = $act->tipo;

                PaquetesActividades::on('costos_principal')->create(
                    [
                        "con_fk_id" => $con_fk_id,
                        "ins_fk_id" => $ins_fk_id,
                        "paq_ano" => $paq_ano,
                        "paq_paquete" => $paquete,
                        "cco_fk_id" => $act->cco_fk_id,
                        "paq_actividad" => $tipo == 0 ? $act->paq_actividad : null,
                        "paq_suministro" => $tipo == 1 ? $act->paq_suministro : null,
                        "paq_frec_realizacion" => $act->paq_frec_realizacion,
                        "paq_cantidad" => $act->paq_cantidad
                    ]
                );
            }
        });

        return array("response" => 0);
    }

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

        \DB::transaction(function() use(&$id, $request) {
            $con_fk_id = $request->input('con_fk_id');
            $ins_fk_id = $request->input('ins_fk_id');
            $paq_ano = $request->input('paq_ano');
            $paquete = $request->input('paq_paquete');
            $act_desc_actividades = $request->input('act_desc_actividades');
            $actividadesSuministros = json_decode($request->input('actividades'));

            // Borrar la infacion anterior
            PaquetesActividades::on('costos_principal')
                               ->where('con_fk_id', $con_fk_id)
                               ->where('ins_fk_id', $ins_fk_id)
                               ->where('paq_ano', $paq_ano)
                               ->where('paq_paquete', $paquete)
                               ->delete();

            // Actualizar con informacion nueva
            Actividades::on('costos_principal')->where('act_pk_id', $paquete)->update(["act_desc_actividades" => $act_desc_actividades]);

            foreach($actividadesSuministros as $act) {
                $tipo = $act->tipo;

                PaquetesActividades::on('costos_principal')->create(
                    [
                        "con_fk_id" => $con_fk_id,
                        "ins_fk_id" => $ins_fk_id,
                        "paq_ano" => $paq_ano,
                        "paq_paquete" => $paquete,
                        "cco_fk_id" => $act->cco_fk_id,
                        "paq_actividad" => $tipo == 0 ? $act->paq_actividad : null,
                        "paq_suministro" => $tipo == 1 ? $act->paq_suministro : null,
                        "paq_frec_realizacion" => $act->paq_frec_realizacion,
                        "paq_cantidad" => $act->paq_cantidad
                    ]
                );
            }
        });

        return array("response" => 0);
    }

    public function borrarActividadesPaquete(Request $request) {
        \DB::transaction(function() use($request) {
            $con_fk_id = $request->input('con_fk_id');
            $ins_fk_id = $request->input('ins_fk_id');
            $paq_ano = $request->input('paq_ano');
            $paq_paquete = $request->input('paq_paquete');

            Actividades::on('costos_principal')->where('act_pk_id', $paq_paquete)->update(["act_desc_actividades" => null]);

            PaquetesActividades::on('costos_principal')
                               ->where("con_fk_id", $con_fk_id)
                               ->where("ins_fk_id", $ins_fk_id)
                               ->where("paq_ano", $paq_ano)
                               ->where("paq_paquete", $paq_paquete)
                               ->delete();
        });
    }

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

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

            fclose($archivo);

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

    private function procesarArchivoActividades($actividades, $con_fk_id, $ins_fk_id, $act_ano) {
        $resultados = new \stdClass();
        $resultados->errores = "";

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

                $actividadesExistentes = [];
                $registrosProcesados = 0;

                // Crear las relaciones existentes en la base de datos
                foreach ($actividadesBd as $actDb) {
                    $actividadesExistentes[$actDb['act_codigo']] = $actDb['act_descripcion'];
                }

                // Errores de los centros de utilidad
                $descripcionLargas = false;
                $camposVacios = false;

                // Revisar el archivo respecto a las relaciones existentes
                foreach($actividades as $actCsv) {
                    $codigo = strtoupper(utf8_encode(trim($actCsv[0])));
                    $descripcion = utf8_encode($actCsv[1]);
                    $paquete = strtoupper(utf8_encode($actCsv[2]));

                    if ($codigo != "" && $descripcion != "" && $paquete != "") {
                        // Descripcion largas
                        if (strlen($codigo) <= 25 && strlen($descripcion) <= 500) {
                            // Existe la actividad
                            if (isset($actividadesExistentes[$codigo])) {
                                // Actualizar si la descripcion es diferente
                                if ($actividadesExistentes[$codigo] != $descripcion) {
                                    Actividades::on('costos_principal')
                                               ->where("con_fk_id", $con_fk_id)
                                               ->where("ins_fk_id", $ins_fk_id)
                                               ->where("act_ano", $act_ano)
                                               ->where("act_codigo", $codigo)
                                    ->update(
                                        [
                                            "act_descripcion" => $descripcion
                                        ]
                                    );

                                    $registrosProcesados++;
                                } else {
                                    $registrosProcesados++;
                                }
                            } else { // No existe, es necesario crearlo
                                $actividad = Actividades::on('costos_principal');

                                $id = $actividad->create(
                                    [
                                        "con_fk_id" => $con_fk_id,
                                        "ins_fk_id" => $ins_fk_id,
                                        "act_ano" => $act_ano,
                                        "act_codigo" => $codigo,
                                        "act_descripcion" => $descripcion,
                                        "act_paquete" => $paquete == "S" ? true : false
                                    ]
                                );

                                $registrosProcesados++;

                                $actividadesExistentes[$codigo] = $descripcion;
                            }
                        } else {
                            $descripcionLargas = true;
                        }
                    } else {
                        $camposVacios = true;
                    }
                }

                // Descripciones largas
                if ($descripcionLargas) {
                    $resultados->errores .= "El codigo es incorrecto o existen descripciones con más caracteres de los permitidos.
                                             El máximo para el codigo son 25 caracteres y 500 caracteres para la descripción.";
                }

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

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

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

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

        return json_encode($resultados);
    }
}
