<?php

namespace App\Models\Presupuestos;

class PresupuestoEncuadernacionesModel extends \App\Models\BaseModel
{
    protected $table = "presupuesto_encuadernaciones";

    /**
     * Whether primary key uses auto increment.
     *
     * @var bool
     */
    protected $useAutoIncrement = true;

    const SORTABLE = [
        0 => "t1.tarifa_encuadernado_id",
        1 => "t2.nombre",
        2 => "t3.nombre",
        3 => "t1.precio_unidad",
        4 => "t1.precio_total"
    ];

    protected $allowedFields = ["presupuesto_id", "tarifa_encuadernado_id", "proveedor_id", "nombre", "precio_total", "precio_unidad", "paginas_por_cuadernillo", "tiempo", "margen"];
    protected $returnType = "App\Entities\Presupuestos\PresupuestoEncuadernacionesEntity";

    protected $useTimestamps = true;
    protected $useSoftDeletes = false;

    protected $createdField = "created_at";
    protected $updatedField = "updated_at";

    public static $labelField = "nombre";

    protected $validationRules = [
        "precio_total" => [
            "label" => "Presupuestos.precioTotal",
            "rules" => "decimal|required",
        ],
    ];

    protected $validationMessages = [
        "precio_total" => [
            "decimal" => "Presupuestos.validation.decimal",
            "requerido" => "Presupuestos.validation.decimal",
        ],
    ];



    public function initPresupuesto($tipo_presupuesto, $solapas, $tirada, $paginas, $ancho, $alto, $POD, $paginasCuadernillo = 32)
    {

        $model = model('App\Models\Presupuestos\TipoPresupuestoServiciosDefectoModel');
        $tarifas_procesar = $model->get_tarifas($tipo_presupuesto, $solapas, "encuadernacion");

        $modelTarifa = model('App\Models\Tarifas\TarifaEncuadernacionModel');
        $tarifas = [];

        foreach ($tarifas_procesar as $tarifa) {

            if ($modelTarifa->isTarifaPorHoras($tarifa['tarifa_id'])) {

                if ($tarifa['tarifa_id'] == 2 || $tarifa['tarifa_id'] == 14 || $tarifa['tarifa_id'] == 17) {  // Rústica cosido hilo vegetal y Rústica cosido hilo vegetal solapas
                    $tiempo = $this->calcularTiempoCosido(16, $paginas, $tirada, $paginasCuadernillo); // ID fija. Cambiar cuando se metan maquinas de corte. Velocidad en minutos
                } else {
                    $tiempo = $this->calcularTiempo(16, $paginas, $tirada); // ID fija. Cambiar cuando se metan maquinas de corte. Velocidad en minutos
                }

                $tarifa_value = $modelTarifa->getTarifaPresupuestoEncuadernacionHoras($tarifa['tarifa_id'], $tiempo, $tirada);
                if (count($tarifa_value) > 0) {

                    $result_array = [];
                    foreach ($tarifa_value as $tarifa_proveedor) {
                        $precio_total = floatval(1.0 * $tarifa_proveedor->precio_hora * $tiempo) * (1 + $tarifa_value[0]->margen / 100.0);
                        if ($tirada >= $POD) {
                            $precio_total += floatval($tarifa_proveedor->tarifa_importe_fijo);
                        }

                        $result_data[0] = round(floatval($precio_total / $tirada), 2); // Precio/unidad
                        $result_data[1] = round($result_data[0] * $tirada, 2);
                        $result_data[2] = $tarifa_proveedor->margen; // margen

                        $datos = [
                            'tarifa_id' => $tarifa['tarifa_id'],
                            'tarifa_nombre' => $tarifa_proveedor->tarifa_enc_nombre,
                            'nombre' => $tarifa_proveedor->tarifa_enc_nombre,
                            'precio_unidad' => $result_data[0],
                            'tiempo' => $tiempo,
                            'total' => $result_data[1],
                            'precio_total' => $result_data[1],
                            'margen' => $result_data[2],
                            'proveedor' => $tarifa_proveedor->proveedor_nombre,
                            'proveedor_id' => $tarifa_proveedor->proveedor_id,
                        ];

                        if ($tarifa['tarifa_id'] == 2 || $tarifa['tarifa_id'] == 14 || $tarifa['tarifa_id'] == 17) {
                            $datos['paginas_por_cuadernillo'] = $paginasCuadernillo;
                        }

                        array_push(
                            $result_array,
                            (object) $datos
                        );
                    }

                    usort($result_array, function ($a, $b) {

                        if ($a->total == $b->total) {
                            return 0;
                        }
                        return ($a->total < $b->total) ? -1 : 1;
                    });

                    array_push($tarifas, $result_array[0]);


                } else {
                    array_push(
                        $tarifas,
                        (object) [
                            'tarifa_id' => $tarifa['tarifa_id'],
                            'tarifa_nombre' => $tarifa['tarifa_nombre'],
                            'nombre' => $tarifa['tarifa_nombre'],
                            'proveedor' => lang('Presupuestos.no_disponible'),
                            'precio_unidad' => 0,
                            'tiempo' => null,
                            'total' => 0,
                            'precio_total' => 0,
                            'margen' => 0,
                        ]
                    );
                }
            } else {
                $tarifa_value = $modelTarifa->getTarifaPresupuestoEncuadernacion($tarifa['tarifa_id'], $paginas, $tirada, $ancho, $alto);
                if (count($tarifa_value) > 0) {

                    $result_array = [];
                    foreach ($tarifa_value as $tarifa_proveedor) {
                        $result_data = $this->calcularTarifa($tarifa_proveedor, $paginas, $tirada, $POD < $tirada ? false : true);
                        array_push($result_array, (object) [
                            'tarifa_id' => $tarifa_proveedor->tarifa_enc_id,
                            'tarifa_nombre' => $tarifa_proveedor->tarifa_enc_nombre,
                            'nombre' => $tarifa_proveedor->tarifa_enc_nombre,
                            'precio_unidad' => $result_data[0],
                            'tiempo' => null,
                            'total' => $result_data[1],
                            'precio_total' => $result_data[1],
                            'margen' => $result_data[2],
                            'proveedor' => $tarifa_proveedor->proveedor_nombre,
                            'proveedor_id' => $tarifa_proveedor->proveedor_id,
                        ]);
                    }

                    usort($result_array, function ($a, $b) {

                        if ($a->total == $b->total) {
                            return 0;
                        }
                        return ($a->total < $b->total) ? -1 : 1;
                    });

                    array_push($tarifas, $result_array[0]);
                } else {
                    array_push(
                        $tarifas,
                        (object) [
                            'tarifa_id' => $tarifa['tarifa_id'],
                            'tarifa_nombre' => $tarifa['tarifa_nombre'],
                            'nombre' => $tarifa['tarifa_nombre'],
                            'proveedor' => lang('Presupuestos.no_disponible'),
                            'precio_unidad' => 0,
                            'tiempo' => null,
                            'total' => 0,
                            'precio_total' => 0,
                            'margen' => 0,
                        ]
                    );
                }
            }
        }

        return $tarifas;
    }


    public function getProveedoresForSelector($tarifa_encuadernacion_id, $paginas, $tirada, $ancho, $alto, $paginasCuadernillo = 32)
    {

        $proveedores = [];
        $modelTarifa = model('App\Models\Tarifas\TarifaEncuadernacionModel');

        if ($modelTarifa->isTarifaPorHoras($tarifa_encuadernacion_id)) {
            $tiempo = $this->calcularTiempoCosido(16, $paginas, $tirada, $paginasCuadernillo); // ID fija. Cambiar cuando se metan maquinas de corte. Velocidad en minutos
            $tarifa_value = $modelTarifa->getTarifaPresupuestoEncuadernacionHoras($tarifa_encuadernacion_id, $tiempo, $tirada);
        } else {
            $tiempo = $this->calcularTiempo(16, $paginas, $tirada); // ID fija. Cambiar cuando se metan maquinas de corte. Velocidad en minutos
            $tarifa_value = $modelTarifa->getTarifaPresupuestoEncuadernacion($tarifa_encuadernacion_id, $paginas, $tirada, $ancho, $alto);
        }
        if (count($tarifa_value) > 0) {
            foreach ($tarifa_value as $tarifa)
                array_push(
                    $proveedores,
                    (object) [
                        'id' => $tarifa->proveedor_id,
                        'text' => $tarifa->proveedor_nombre,
                    ]
                );
        }
        return $proveedores;
    }

    public function getPrecioTarifa($tarifa_encuadernacion_id, $paginas, $tirada, $ancho, $alto, $proveedor_id, $POD)
    {

        $modelTarifa = model('App\Models\Tarifas\TarifaEncuadernacionModel');
        if ($proveedor_id != -1) {
            $tarifa_value = $modelTarifa->getTarifaPresupuestoEncuadernacion($tarifa_encuadernacion_id, $paginas, $tirada, $ancho, $alto, $proveedor_id);
        } else {
            $tarifa_value = $modelTarifa->getTarifaPresupuestoEncuadernacion($tarifa_encuadernacion_id, $paginas, $tirada, $ancho, $alto);
        }
        if (count($tarifa_value) > 0) {

            $ret_array = [];
            foreach ($tarifa_value as $tarifa) {

                $result_data = $this->calcularTarifa($tarifa, $paginas, $tirada, $POD < $tirada ? false : true);
                array_push($ret_array, (object) [
                    'tarifa_id' => $tarifa->tarifa_enc_id,
                    'tarifa_nombre' => $tarifa->tarifa_enc_nombre,
                    'nombre' => $tarifa->tarifa_enc_nombre,
                    'precio_unidad' => $result_data[0],
                    'tiempo' => null,
                    'total' => $result_data[1],
                    'precio_total' => $result_data[1],
                    'margen' => $result_data[2],
                    'proveedor' => $tarifa->proveedor_nombre,
                    'proveedor_id' => $tarifa->proveedor_id,
                ]);
            }

            usort($ret_array, function ($a, $b) {

                if ($a->total == $b->total) {
                    return 0;
                }
                return ($a->total < $b->total) ? -1 : 1;
            });
            return $ret_array;
        } else {
            $ret_array[] = (object) [
                'tarifa_id' => $tarifa_encuadernacion_id,
                'tarifa_nombre' => $modelTarifa->getNombreTarifaEncuadernacion($tarifa_encuadernacion_id)[0]->nombre,
                'nombre' => $modelTarifa->getNombreTarifaEncuadernacion($tarifa_encuadernacion_id)[0]->nombre,
                'proveedor' => lang('Presupuestos.no_disponible'),
                'precio_unidad' => 0,
                'tiempo' => null,
                'total' => 0,
                'precio_total' => 0,
                'margen' => 0,
            ];
            return $ret_array;
        }
        return [];
    }

    public function getPrecioTarifaHoras($tarifa_encuadernacion_id, $paginas, $tirada, $proveedor_id, $POD, $paginas_cuadernillo = 32)
    {

        $modelTarifa = model('App\Models\Tarifas\TarifaEncuadernacionModel');

        if ($tarifa_encuadernacion_id == 2 || $tarifa_encuadernacion_id == 14 || $tarifa_encuadernacion_id == 17) {  // Rústica cosido hilo vegetal y Rústica cosido hilo vegetal solapas y coser hilo
            $tiempo = $this->calcularTiempoCosido(16, $paginas, $tirada, $paginas_cuadernillo); // ID fija. Cambiar cuando se metan maquinas de corte. Velocidad en minutos
        } else {
            $tiempo = $this->calcularTiempo(16, $paginas, $tirada); // ID fija. Cambiar cuando se metan maquinas de corte. Velocidad en minutos
        }

        $tarifa_value = $modelTarifa->getTarifaPresupuestoEncuadernacionHoras($tarifa_encuadernacion_id, $tiempo, $tirada, $proveedor_id);
        if (count($tarifa_value) > 0) {

            $ret_array = [];
            foreach ($tarifa_value as $tarifa_proveedor) {
                $precio_total = floatval(1.0 * $tarifa_proveedor->precio_hora * $tiempo) * (1 + $tarifa_value[0]->margen / 100.0);
                if ($tirada >= $POD) {
                    $precio_total += floatval($tarifa_proveedor->tarifa_importe_fijo);
                }

                $tarifa_precio_min = floatval($tarifa_proveedor->tarifa_precio_min);

                if ($tarifa_precio_min > $precio_total) {
                    $precio_total = $precio_total - ($precio_total * $margen / 100.0);
                    $margen = round(100.0 * (floatval($tarifa_precio_min) - $precio_total) / floatval($tarifa_precio_min), 0);
                    $precio_total = floatval($tarifa_precio_min);
                }

                $precio_total = round($precio_total, 2);

                $result_data[0] = round(floatval($precio_total / $tirada), 2); // Precio/unidad
                $result_data[1] = round($result_data[0] * $tirada, 2);
                $result_data[2] = $tarifa_proveedor->margen; // margen


                array_push(
                    $ret_array,
                    (object) [
                        'tarifa_id' => $tarifa_proveedor->tarifa_enc_id,
                        'tarifa_nombre' => $tarifa_proveedor->tarifa_enc_nombre,
                        'nombre' => $tarifa_proveedor->tarifa_enc_nombre,
                        'precio_unidad' => $result_data[0],
                        'tiempo' => $tiempo,
                        'paginas_por_cuadernillo' => $paginas_cuadernillo,
                        'precio_total' => $result_data[1],
                        'total' => $result_data[1],
                        'margen' => $result_data[2],
                        'proveedor' => $tarifa_proveedor->proveedor_nombre,
                        'proveedor_id' => $tarifa_proveedor->proveedor_id,
                    ]
                );
            }

            usort($ret_array, function ($a, $b) {

                if ($a->total == $b->total) {
                    return 0;
                }
                return ($a->total < $b->total) ? -1 : 1;
            });

            return $ret_array;
        } else {
            $ret_array[] = (object) [
                'tarifa_id' => $tarifa_encuadernacion_id,
                'tarifa_nombre' => $modelTarifa->getNombreTarifaEncuadernacion($tarifa_encuadernacion_id)[0]->nombre,
                'nombre' => $modelTarifa->getNombreTarifaEncuadernacion($tarifa_encuadernacion_id)[0]->nombre,
                'proveedor' => lang('Presupuestos.no_disponible'),
                'precio_unidad' => 0,
                'tiempo' => null,
                'paginas_por_cuadernillo' => null,
                'total' => 0,
                'precio_total' => 0,
                'margen' => 0,
            ];
            return $ret_array;
        }
    }


    private function calcularTarifa($tarifa, $paginas, $ejemplares, $is_POD = false)
    {

        $precio_unidad = floatval($tarifa->precio_max) - (floatval($tarifa->precio_max) - floatval($tarifa->precio_min)) / ($tarifa->paginas_max - $tarifa->paginas_min) * ($paginas - $tarifa->paginas_min);
        if ($paginas > $tarifa->paginas_max)
            $precio_unidad = $tarifa->precio_max;
        $precio_unidad = $precio_unidad * (1 + floatval($tarifa->margen) / 100.0);

        if (!$is_POD) {
            $precio_unidad += floatval($tarifa->tarifa_importe_fijo) / floatval($ejemplares);
        }

        $precio_unidad = round($precio_unidad, 2);

        $total = $precio_unidad * $ejemplares;
        $margen = floatval($tarifa->margen);
        $tarifa_precio_min = floatval($tarifa->tarifa_precio_min);

        if ($tarifa_precio_min > $total) {
            $total = $total - ($total * $margen / 100.0);
            $margen = round(100.0 * (floatval($tarifa_precio_min) - $total) / floatval($tarifa_precio_min), 0);
            $total = floatval($tarifa_precio_min);
            $precio_unidad = round(floatval($total / $ejemplares), 2);
        }

        return [$precio_unidad, $total, $margen];
    }


    public function getIdFromTarifa($tarifa_id)
    {

        $builder = $this->db
            ->table($this->table . " t1")
            ->select(
                "t1.id AS id"
            );
        $builder->where('t1.tarifa_encuadernado_id', $tarifa_id);
        return $builder;
    }


    public function deleteAllServicios($presupuesto_id)
    {

        $this->db
            ->table($this->table . " t1")
            ->where('presupuesto_id', $presupuesto_id)
            ->delete();
    }

    public function deleteServiciosNotInArray($presupuesto_id, $tarifas_id)
    {

        $builder = $this->db
            ->table($this->table . " t1");
        $builder->where('presupuesto_id', $presupuesto_id);
        foreach ($tarifas_id as $id) {
            $builder->where('tarifa_encuadernado_id !=', $id);
        }
        $builder->delete();
    }

    public function updateTarifas($presupuesto_id, $tarifas)
    {

        foreach ($tarifas as $tarifa) {

            $proveedor = $tarifa->proveedor_id == 'undefined' ? 'NULL' : $tarifa->proveedor_id;
            $builder = $this->db
                ->table($this->table . " t1");
            $builder->select("id");
            $builder->where('presupuesto_id', $presupuesto_id);
            $builder->where('tarifa_encuadernado_id', $tarifa->tarifa_id);
            $result = $builder->get()->getResultObject();
            $paginas_cuadernillo = $tarifa->paginas_por_cuadernillo ?? null;
            if (count($result) > 0) {
                $this->db
                    ->table($this->table . " t1")
                    ->where('presupuesto_id', $presupuesto_id)
                    ->where('tarifa_encuadernado_id', $tarifa->tarifa_id)
                    ->set('proveedor_id', $proveedor)
                    ->set('precio_unidad', $tarifa->precio_unidad)
                    ->set('tiempo', $tarifa->tiempo)
                    ->set('precio_total', $tarifa->precio_total)
                    ->set('margen', $tarifa->margen)
                    ->set('paginas_por_cuadernillo', $paginas_cuadernillo)
                    ->update();


            } else {
                $this->db
                    ->table($this->table . " t1")
                    ->set('presupuesto_id', $presupuesto_id)
                    ->set('tarifa_encuadernado_id', $tarifa->tarifa_id)
                    ->set('proveedor_id', $proveedor, false)
                    ->set('precio_unidad', $tarifa->precio_unidad)
                    ->set('tiempo', $tarifa->tiempo)
                    ->set('precio_total', $tarifa->precio_total)
                    ->set('margen', $tarifa->margen)
                    ->insert();
            }
        }
    }

    /**
     * Get resource data.
     *
     * @param string $search
     *
     * @return \CodeIgniter\Database\BaseBuilder
     */
    public function getResource($presupuesto_id = -1)
    {
        $builder = $this->db
            ->table($this->table . " t1")
            ->select(
                "t1.id AS id, t1.tarifa_encuadernado_id AS tarifa_encuadernado_id, t1.precio_unidad AS precio_unidad, t1.tiempo AS tiempo,
                t1.precio_total AS precio_total, t1.margen AS margen, t2.nombre AS nombre, t1.proveedor_id AS proveedor_id, t3.nombre AS proveedor,
                t1.paginas_por_cuadernillo AS paginas_por_cuadernillo"
            );

        $builder->where('t1.presupuesto_id', $presupuesto_id);
        $builder->join("tarifa_encuadernacion t2", "t1.tarifa_encuadernado_id = t2.id", "left");
        $builder->join("lg_proveedores t3", "t1.proveedor_id = t3.id", "left");

        return $builder;
    }

    private function calcularTiempo($maquina_id, $paginas, $tirada)
    {

        $maquinaModel = model("App\Models\Configuracion\MaquinaModel");
        $cuadernillos_libro = $paginas / 4;
        $cuadernillos_pedido = $cuadernillos_libro * $tirada;
        $velocidad = $maquinaModel->getVelocidad($maquina_id);
        $temp = round($cuadernillos_pedido / ($velocidad * 60.0), 2);
        if ($temp < 0.01)
            return 0.01;
        else
            return $temp;
        
    }

    private function calcularTiempoCosido($maquina_id, $paginas, $tirada, $cuadernillos_por_pagina = 32)
    {

        $maquinaModel = model("App\Models\Configuracion\MaquinaModel");
        $velocidad = $maquinaModel->getVelocidad($maquina_id); // cuadernillos por minuto
        $cuadernillos_libro = ceil($paginas / intval($cuadernillos_por_pagina));
        $cuadernillos_pedido = $cuadernillos_libro * $tirada;
        $temp = round($cuadernillos_pedido / ($velocidad * 60.0), 2);
        if ($temp < 0.01)
            return 0.01;
        else
            return $temp;
    }
}
