<?php

namespace App\Models\Pedidos;

use App\Entities\Produccion\OrdenTrabajoEntity;
use App\Models\OrdenTrabajo\OrdenTrabajoModel;

use function PHPSTORM_META\map;

class PedidoModel extends \App\Models\BaseModel
{
    protected $table = "pedidos";

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

    const SORTABLE_TODOS = [
        0 => "t1.id",
        1 => "t1.updated_at",
        2 => "t1.fecha_entrega_real",
        3 => "t4.nombre",
        4 => "t5.first_name",
        5 => "t3.titulo",
        6 => "t6.ubicacion",
        7 => "t3.inc_rei",
        8 => "t3.paginas",
        9 => "t3.tirada",
        10 => "t3.total_aceptado",
        11 => "t1.estado"
    ];

    protected $allowedFields = [
        "total_precio",
        "total_tirada",
        "estado",
        "inaplazable",
        "user_created_id",
        "user_updated_id",
        "user_validated_id",
        "fecha_entrega_real",
        "fecha_impresion",
        "fecha_encuadernado",
        "fecha_entrega_externo",
        "fecha_entrega_real_change_user_id",
        "fecha_impresion_change_user_id",
        "fecha_encuadernado_change_user_id",
        "fecha_entrega_externo_change_user_id",
        "inaplazable_change_user_id",
        "created_at",
        "updated_at",
        "validated_at",
    ];
    protected $returnType = "App\Entities\Pedidos\PedidoEntity";

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

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

    public static $labelField = "id";

    public function obtenerDatosForm($pedido_id)
    {
        $builder = $this->db
            ->table($this->table . " t1")
            ->select(
                "t4.id AS cliente_id, t4.nombre AS cliente, CONCAT(t5.first_name, ' ', t5.last_name) AS comercial"
            );

        $builder->join("pedidos_linea t2", "t2.pedido_id = t1.id", "left");
        $builder->join("presupuestos t3", "t2.presupuesto_id = t3.id", "left");
        $builder->join("clientes t4", "t4.id = t3.cliente_id", "left");
        $builder->join("users t5", "t5.id = t4.comercial_id", "left");

        $builder->where("t1.id", $pedido_id);

        return $builder->get()->getResultObject();
    }

    public function obtenerDatosForFactura($pedido_id = -1){

        $builder = $this->db
            ->table($this->table . " t1")
            ->select("
                t3.cliente_id, t4.nombre as cliente_nombre, t4.cif as cliente_cif, t4.direccion as cliente_direccion,
                t5.nombre as cliente_pais, t4.cp as cliente_cp, t4.ciudad as cliente_ciudad, t6.nombre as cliente_provincia
            "
            )
            ->join("pedidos_linea t2", "t2.pedido_id = t1.id", "left")
            ->join("presupuestos t3", "t2.presupuesto_id = t3.id", "left")
            ->join("clientes t4", "t4.id = t3.cliente_id", "left")
            ->join("lg_paises t5", "t5.id = t4.pais_id", "left")
            ->join("lg_provincias t6", "t6.id = t4.provincia_id", "left");

        $builder->where("t1.id", $pedido_id);
        return $builder->get()->getResultObject();
    }

    public function addFacturaPedidoLinea($pedido_id, $factura_id, $cantidad)
    {
        return $this->db
            ->table("facturas_pedidos_lineas")
            ->insert([
                "factura_id" => $factura_id,
                "pedido_id" => $pedido_id,
                "cantidad" => $cantidad
            ]);
    }

    public function obtenerLineasPedido($pedido_id)
    {
        $builder = $this->db
            ->table($this->table . " t1")
            ->select(
                "t2.presupuesto_id, t3.total_aceptado, t2.descripcion, t2.cantidad"
            );
        $builder->where("t1.id", $pedido_id);
        $builder->join("pedidos_linea t2", "t2.pedido_id = t1.id", "left");
        $builder->join("presupuestos t3", "t2.presupuesto_id = t3.id", "left");
        $model_presupuesto = model("App\Models\Presupuestos\PresupuestoModel");
        $lineasPresupuesto = [];

        foreach ($builder->get()->getResultObject() as $row) {
            if($row->descripcion == null){
                array_push($lineasPresupuesto, $model_presupuesto->generarLineaPedido($row->presupuesto_id)[0]);
            }
            else{
                $presupuesto = (object) [
                    'numero' => $row->presupuesto_id,
                    'unidades' => $row->cantidad,
                    'total' => $row->total_aceptado,
                    'concepto' => $row->descripcion,
                ];
                array_push($lineasPresupuesto, $presupuesto);
            }
            
        }
        $builder->groupBy("t1.id");

        return $lineasPresupuesto;
    }
    public function getPedidoPresupuestoTipoImpresion(int $presupuesto_id): array|object|null
    {
        $q = $this->db->table($this->table)
            ->select(
                [
                    'tipos_presupuesto.codigo',
                    'presupuestos.solapas'
                ]
            )
            ->join('tipos_presupuestos', 'tipos_presupuestos.id = presupuestos.tipo_impresion_id', 'left')
            ->where('presupuestos.id', $presupuesto_id);
        return $q->get()->getFirstRow();
    }
    public function getPedidoClientePresupuesto(int $pedido_id)
    {
        $query = $this->db->table($this->table)
            ->select([
                'pedidos.id as pedidoId',
                'clientes.nombre as customerName',
                'presupuestos.total_aceptado as totalAceptado',
                'presupuestos.id as presupuestoId',
                'presupuestos.cliente_id as presupuestoClienteId',
                'presupuestos.margen',
                'presupuestos.inc_rei',
                'presupuestos.tirada',
                'presupuestos.tirada',
                'presupuestos.titulo',
                'presupuestos.paginas',
                'presupuestos.solapas',
                'presupuestos.solapas_ancho',
                'presupuestos.marcapaginas',
                'presupuestos.comentarios_cliente',
                'presupuestos.comentarios_safekat',
                'presupuestos.papel_formato_personalizado',
                'presupuestos.papel_formato_ancho as papelAnchoPersonalidado ',
                'presupuestos.papel_formato_alto as papelAltoPersonalidado',
                'tipos_presupuestos.codigo as codigoTipoImpresion',
                'lg_papel_formato.ancho as lgPapelFormatoAncho ',
                'lg_papel_formato.alto as lgPapelFormatoAlto',


            ])
            ->join('pedidos_linea', 'pedidos_linea.id = pedidos.id', 'left')
            ->join('presupuestos', 'presupuestos.id = pedidos_linea.presupuesto_id', 'left')
            ->join('presupuesto_ficheros', 'presupuesto_ficheros.presupuesto_id = presupuestos.id', 'left')
            ->join('tipos_presupuestos', 'tipos_presupuestos.id = presupuestos.tipo_impresion_id', 'left')
            // ->join('presupuesto_linea','presupuestos.id = presupuesto_linea.presupuesto_id','left')
            ->join('clientes', 'clientes.id = presupuestos.cliente_id', 'left')
            ->join('lg_papel_formato', 'lg_papel_formato.id = presupuestos.papel_formato_id', 'left')
            ->where('pedidos.id', $pedido_id);
        $cliente_presupuesto = $query->get()->getFirstRow();
        return $cliente_presupuesto;
    }
    public function getPedidoPresupuestoLineas(int $pedido_id)
    {
        $query = $this->db->table($this->table)
            ->select([
                'pedidos.id as pedidoId',
                'presupuesto_linea.tipo',
                'presupuesto_linea.paginas',
                'presupuesto_linea.gramaje',
                'lg_papel_generico.code as papelCode',
            ])
            ->join('pedidos_linea', 'pedidos_linea.id = pedidos.id', 'left')
            ->join('presupuestos', 'presupuestos.id = pedidos_linea.presupuesto_id', 'left')
            ->join('presupuesto_linea', 'presupuestos.id = presupuesto_linea.presupuesto_id', 'left')
            ->join('lg_papel_generico', 'lg_papel_generico.id = presupuesto_linea.papel_id', 'left')
            ->where('pedidos.id', $pedido_id);

        $pedido_presupuesto_lineas = $query->get()->getResultObject();
        return $pedido_presupuesto_lineas;
    }
    public function getPedidoPresupuestoDirecciones($pedido_id)
    {
        $query = $this->db->table($this->table)
            ->select([
                'pedidos.id as pedidoId',
                'presupuestos.id as presupuestoId',
                'clientes.nombre as customerName',
                'presupuesto_direcciones.*',
                'lg_paises.code3 as paisCode3'
            ])
            ->join('pedidos_linea', 'pedidos_linea.id = pedidos.id', 'left')
            ->join('presupuestos', 'presupuestos.id = pedidos_linea.presupuesto_id', 'left')
            ->join('presupuesto_direcciones', 'presupuestos.id = presupuesto_direcciones.presupuesto_id', 'left')
            ->join('clientes', 'clientes.id = presupuestos.cliente_id', 'left')
            ->join('cliente_direcciones', 'clientes.id = cliente_direcciones.cliente_id', 'left')
            ->join('lg_paises', 'lg_paises.id = presupuesto_direcciones.pais_id', 'left')
            ->where('pedidos.id', $pedido_id);
        $pedido_cliente_direcciones = $query->get()->getResultObject();
        return $pedido_cliente_direcciones;
    }
    public function getPedidoPresupuestoFicheros($pedido_id)
    {
        $query = $this->db->table($this->table)
            ->select([
                'presupuesto_ficheros.nombre as fileName',
                'presupuesto_ficheros.file_path as filePath'
            ])
            ->join('pedidos_linea', 'pedidos_linea.id = pedidos.id', 'left')
            ->join('presupuestos', 'presupuestos.id = pedidos_linea.presupuesto_id', 'left')
            ->join('presupuesto_ficheros', 'presupuesto_ficheros.presupuesto_id = presupuestos.id', 'left')
            ->where('pedidos.id', $pedido_id);
        $presupuesto_ficheros = $query->get()->getFirstRow();
        return $presupuesto_ficheros;
    }


    public function getPedidosClienteForm($cliente_id = -1){
        $builder = $this->db
        ->table($this->table . " p")
            ->select('p.id, p.created_at as fecha, p.fecha_entrega_real as fecha_entrega, 
                pr.paginas as paginas, p.total_tirada, p.total_precio, p.estado')
            ->join('pedidos_linea pl', 'pl.pedido_id = p.id', 'left')
            ->join('presupuestos pr', 'pr.id = pl.presupuesto_id', 'left')
            //->where('pr.deleted_at IS NULL')
            ->where('pr.cliente_id', $cliente_id)
            ->groupBy('p.id');
        return $builder;
    }

    /**
     * Crea una orden de trabajo asociada al pedido
     *
     * @param integer $pedido_id
     * @return void
     */
    public function createOrdenTrabajo(int $pedido_id)
    {
        $otModel = model(OrdenTrabajoModel::class);
        $ot = new OrdenTrabajoEntity(["pedido_id" => $pedido_id]);
        $existOt = $this->hasOrdenTrabajo($pedido_id);
        if ($existOt) {
            $ot = $otModel->find($pedido_id);
            return $ot;
        }
        $otModel->updateMaquinas($ot);
    }

    /**
     * Comprueba si el pedido tiene ya una orden de trabajo asociada
     *
     * @param integer $pedido_id
     * @return boolean
     */
    public function hasOrdenTrabajo(int $pedido_id): bool
    {
        $hasOrdenTrabajo = false;
        $q = $this->builder()->select("orden_trabajo.pedido_id")
            ->join("ordenes_trabajo", "ordenes_trabajo.pedido_id = pedidos.id", "left")
            ->where("ordenes_trabajo.pedido_id", $pedido_id)->countAllResults();
        if ($q > 0) {
            $hasOrdenTrabajo = true;
        }
        return $hasOrdenTrabajo;
    }
}
