<?php

namespace App\Controladores;

use App\Modelos\Divisa;
use App\Modelos\Divisafactor;
use Core\Controller;
use Core\Librerias\Http;
use Core\Librerias\Module;
use Core\Vista;

final class DivisasControlador extends Controller
{
    private $divisas;
    private $array_errors = [];
    private $module;

    public function __construct()
    {
        parent::__construct();
        $this->module   = new Module();
        $this->divisas  = new Divisa();
    }

    public function index()
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {
            return Vista::viewAJAX('divisas/index');
        }
    }

    public function obtenerDivisasActivas()
    {
        if ('GET' === $_SERVER['REQUEST_METHOD']) {
            $divisas = $this->divisas->where(['div_status' => 1]);
            $list = [];
            if (is_countable($divisas) && count($divisas)) {
                foreach ($divisas as $row) {
                    $list[] = [
                        'id' => $row['div_id'],
                        'nombre' => $row['div_nombre'],
                        'descripcion' => $row['div_descripcion']
                    ];
                }
            }
            Http::json_response($list);
        }
    }

    public function obtenerDivisas()
    {
        if ('GET' === $_SERVER['REQUEST_METHOD']) {
            $divisas = $this->divisas->todos();
            $list = [];
            if (is_countable($divisas) && count($divisas)) {
                foreach ($divisas as $row) {
                    $list[] = [
                        'id' => $row['div_id'],
                        'nombre' => $row['div_nombre'],
                        'simbolo' => $row['div_simbolo'],
                        'descripcion' => $row['div_descripcion'],
                        'decimal' => $row['div_decimal'],
                        'partedecimal' => $row['div_partedecimal'],
                        'predeterminado' => $row['div_predeterminado'],
                        'facturar' => $row['div_facturar'],
                        'estatus' => $row['div_status'] ? true : false
                    ];
                }
            }
            Http::json_response($list);
        }
    }

    public function obtenerDivisasDiferente(int $id_divisa)
    {
        if ('GET' === $_SERVER['REQUEST_METHOD']) {

            $id = filter_var($id_divisa, FILTER_SANITIZE_NUMBER_INT);

            $divisas = $this->divisas->where(['div_id<>' => $id]);
            $list = [];

            if (is_countable($divisas) && count($divisas)) {
                foreach ($divisas as $row) {
                    $divisas_fac = $this->divisas->consultar("SELECT df_factor FROM app_divisas_factor WHERE df_divid_master = $id AND df_divid = {$row['div_id']}")->row();
                    if ($divisas_fac) {
                        $divisas_fac = $divisas_fac['df_factor'];
                    } else {
                        $divisas_fac = 0;
                    }
                    $list[] = [
                        'id' => $row['div_id'],
                        'nombre' => $row['div_nombre'],
                        'descripcion' => $row['div_descripcion'],
                        'factor' => $divisas_fac
                    ];
                }
            }

            Http::json_response($list);
        }
    }

    public function guardar()
    {
        if ('POST' === $_SERVER['REQUEST_METHOD']) {

            if (empty($_POST['nombre']))
                $this->array_errors[] = 'El campo Nombre es obligatorio';
            if (empty($_POST['descripcion']))
                $this->array_errors[] = 'El campo Descripción es obligatorio';
            if (empty($_POST['simbolo']))
                $this->array_errors[] = 'El campo Simbolo es obligatorio';
            if (empty($_POST['decimal']))
                $this->array_errors[] = 'El campo Parte decimal es obligatorio';

            if (empty($this->array_errors)) {

                $div_nombre         = $this->solicitud->sanitize($_POST['nombre'], FILTER_SANITIZE_STRING);
                $div_descripcion    = $this->solicitud->sanitize($_POST['descripcion'], FILTER_SANITIZE_STRING);
                $div_simbolo        = $this->solicitud->sanitize($_POST['simbolo'], FILTER_SANITIZE_STRIPPED);
                $div_partedecimal   = filter_input(INPUT_POST, 'partedecimal', FILTER_SANITIZE_STRIPPED);
                $div_decimal        = $_POST['decimal'] ?? 0;
                $div_decimal        = filter_var($div_decimal, FILTER_VALIDATE_INT);

                if ($div_partedecimal != ',' && $div_partedecimal != '.')
                    $this->array_errors[] = 'El campo parte decimal solo acepta (.) o (,)';
                if ($div_decimal) {
                    if ($div_decimal < 0 || $div_decimal > 2)
                        $this->array_errors[] = 'La cantidad de decimales permitidos va de 0 a 2';
                } else {
                    $this->array_errors[] = 'El campo decimal solo puede ser numerico';
                }

                if (empty($this->array_errors)) {

                    if (empty($_POST['id'])) {

                        if ($this->divisas->where(['div_nombre' => $div_nombre]))
                            $this->array_errors[] = 'Lo siento ya existe una divisa de igual nombre';
                        if ($this->divisas->where(['div_descripcion' => $div_descripcion]))
                            $this->array_errors[] = 'Lo siento ya existe una divisa de igual nombre';

                        if (empty($this->array_errors) && $this->divisas->chueqearPredeterminados()) {
                            $div_predeterminado = 0;
                        }
                    } else {

                        $div_id = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT);

                        if ($this->divisas->where(['div_id<>' => $div_id, 'div_nombre' => $div_nombre]))
                            $this->array_errors[] = 'Lo siento ya existe una divisa de igual nombre';
                        if ($this->divisas->where(['div_id<>' => $div_id, 'div_descripcion' => $div_descripcion]))
                            $this->array_errors[] = 'Lo siento ya existe una divisa de igual nombre';

                        if (empty($this->array_errors) && $this->divisas->chueqearPredeterminadosDiferente($div_id)) {
                            $div_predeterminado = 0;
                        }
                    }

                    if (empty($this->array_errors)) {

                        $data_form = [
                            'div_nombre' => $div_nombre,
                            'div_descripcion' => $div_descripcion,
                            'div_simbolo' => $div_simbolo,
                            'div_decimal' => $div_decimal,
                            'div_partedecimal' => $div_partedecimal,
                            'div_predeterminado' => $div_predeterminado,
                            'div_locale' => ($div_partedecimal == ',') ? 'de-DE' : 'en-US'
                        ];

                        if (empty($_POST['id'])) {
                            Http::json_response($this->divisas->guardar($data_form, true));
                        } else {
                            Http::json_response($this->divisas->editar($div_id, $data_form));
                        }
                    }
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function divisaFactor()
    {
        if ('POST' === $_SERVER['REQUEST_METHOD']) {
            $id_master = filter_input(INPUT_POST, 'id_master', FILTER_SANITIZE_NUMBER_INT);
            $id = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT);
            Http::json_response($this->divisas->divisaFactor($id_master, $id));
        }
    }

    public function guardarFactores()
    {
        if ('POST' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if ($this->module->has_module_action_permission('configuracion', 'factor', $_SESSION['user_data']['emp_id'])) {

                $id_divisa_master = filter_input(INPUT_POST, 'id_divisa_master', FILTER_VALIDATE_INT);
                $divisas_fac = filter_input(INPUT_POST, 'divisas');
                $divisas_fac = json_decode($divisas_fac, true);

                if (is_countable($divisas_fac) && count($divisas_fac)) {

                    $newDivisaFactor = new Divisafactor();
                    $divisas = $this->divisas->consultar("SELECT * FROM app_divisas")->all();
                    $unico = uniqid();
                    $fecha = date('Y-m-d H:i:s');

                    try {

                        $newDivisaFactor->transactionBegin();

                        foreach ($divisas_fac as $row) {

                            $id_encontrado = $newDivisaFactor->divisaExiste($id_divisa_master, $row['id']);

                            $row['factor'] = convertir_a_float($row['factor']);

                            if ($id_encontrado) {
                                $newDivisaFactor->editar($id_encontrado['df_id'], [
                                    'df_factor' => $row['factor']
                                ], 'app_divisas_factor', 'df_id');
                            } else {
                                $newDivisaFactor->guardar([
                                    'df_divid_master' => $id_divisa_master,
                                    'df_divid' => $row['id'],
                                    'df_factor' => $row['factor']
                                ], true, 'app_divisas_factor');
                            }

                            $id_encontrado_dos = $newDivisaFactor->divisaExiste($row['id'], $id_divisa_master);

                            if ($id_encontrado_dos) {
                                $newDivisaFactor->editar($id_encontrado_dos['df_id'], [
                                    'df_factor' => (1 / $row['factor'])
                                ], 'app_divisas_factor', 'df_id');
                            } else {
                                $newDivisaFactor->guardar([
                                    'df_divid_master' => $row['id'],
                                    'df_divid' => $id_divisa_master,
                                    'df_factor' => (1 / $row['factor'])
                                ], true, 'app_divisas_factor');
                            }
                        }

                        $bitacora_factor = $newDivisaFactor->todos();

                        foreach ($divisas as $div) {

                            $comparado = [];

                            foreach ($bitacora_factor as $row) {

                                if ($div['div_id'] != $row['df_divid']) {

                                    if (!in_array($row['df_divid'], $comparado)) {

                                        $div_encontro = $newDivisaFactor->consultar("SELECT df_factor FROM app_divisas_factor WHERE df_divid_master = {$div['div_id']} AND df_divid = {$row['df_divid']}")->row();

                                        if ($div_encontro) {
                                            $newDivisaFactor->guardar([
                                                'bifac_divid_uno' => $div['div_id'],
                                                'bifac_divid_dos' => $row['df_divid'],
                                                'bifac_factor' => $div_encontro['df_factor'],
                                                'bifac_fecha' => $fecha,
                                                'bitfac_relacion' => $unico
                                            ], true, 'app_bitacora_factor');
                                        } else {

                                            $div_factor_uno = $newDivisaFactor->consultar("SELECT df_factor FROM app_divisas_factor WHERE df_divid_master = $id_divisa_master AND df_divid = {$div['div_id']}")->row();
                                            $div_factor_dos = $newDivisaFactor->consultar("SELECT df_factor FROM app_divisas_factor WHERE df_divid_master = $id_divisa_master AND df_divid = {$row['df_divid']}")->row();

                                            $newDivisaFactor->guardar([
                                                'bifac_divid_uno' => $div['div_id'],
                                                'bifac_divid_dos' => $row['df_divid'],
                                                'bifac_factor' => ($div_factor_uno['df_factor'] / $div_factor_dos['df_factor']),
                                                'bifac_fecha' => $fecha,
                                                'bitfac_relacion' => $unico
                                            ], true, 'app_bitacora_factor');
                                        }
                                    }

                                    $comparado[] = $row['df_divid'];
                                }
                            }
                        }

                        $newDivisaFactor->transactionCommit();
                    } catch (\Throwable $th) {
                        $newDivisaFactor->transactionRollBack();
                        $this->array_errors[] = $th;
                    }
                } else {
                    $this->array_errors[] = 'Campos incorrectos';
                }
            } else {
                $this->array_errors[] = 'Acceso prohibido no posee permisos para actualizar el fator de las divisas.';
            }

            if (empty($this->array_errors)) {
                Http::json_response(true);
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }


    public function modificarEstatus(int $id_divisa)
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            $id = filter_var($id_divisa, FILTER_SANITIZE_NUMBER_INT);
            $estatus = $this->divisas->obtener($id);

            if ($estatus['div_predeterminado'] == 1 && $estatus['div_status'] == 1) {
                $this->array_errors[] = 'No se puede modificar el estatus de la divisa ya que se ecuentra como predeterminada';
            } else {
                Http::json_response($this->divisas->editar($id, [
                    'div_status'  => $estatus['div_status'] ? 0 : 1
                ]));
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function establecerPredeterminado(int $id_divisa)
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            $id = filter_var($id_divisa, FILTER_SANITIZE_NUMBER_INT);
            $estatus = $this->divisas->obtener($id);

            if ($estatus['div_predeterminado'] == 1) {
                if ($this->divisas->chueqearPredeterminadosDiferente($id)) {
                    Http::json_response($this->divisas->establecerPredeterminado($id, 0));
                } else {
                    $this->array_errors[] = 'Lo siento debe quedar alguna divisa en estado de predeterminada.';
                }
            } else {
                if ($this->divisas->establecerPredeterminado($id, 1)) {
                    Http::json_response($this->divisas->editar($id, [
                        'div_id' => $id,
                        'div_status' => 1
                    ]));
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function establecerPredeterminadoFactura(int $id_divisa)
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            $id = filter_var($id_divisa, FILTER_SANITIZE_NUMBER_INT);
            $estatus = $this->divisas->obtener($id);

            if ($estatus['div_facturar'] == 1) {
                if ($this->divisas->chueqearPredeterminadoFacturaDiferente($id)) {
                    Http::json_response($this->divisas->establecerPredeterminadoFacturar($id, 0));
                } else {
                    $this->array_errors[] = 'Lo siento debe quedar alguna divisa en estado de predeterminada.';
                }
            } else {
                if ($this->divisas->establecerPredeterminadoFacturar($id, 1)) {
                    Http::json_response($this->divisas->editar($id, [
                        'div_id' => $id,
                        'div_status' => 1
                    ]));
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function eliminar(int $id_divisa)
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {
            $id = filter_var($id_divisa, FILTER_SANITIZE_NUMBER_INT);
            if ($this->divisas->divisaForanea($id)) {
                $this->array_errors[] = 'La divisa no de puede eliminar ya que se encuentra relacionada con algun metodo de pago';
            } else {
                Http::json_response($this->divisas->eliminar($id));
            }
            Http::json_response(['errors' => $this->array_errors]);
        }
    }
}
