<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Stock_model extends CI_Model
{
	/* =========================
	   ORQUESTADOR
	   ========================= */

	public function productos_con_movimiento($fecha)
	{
		$rows = array_merge(
			$this->mov_ventas($fecha),
			$this->mov_traspasos_origen($fecha),
			$this->mov_traspasos_destino($fecha),
			$this->mov_compras($fecha)
		);

		return $this->unique($rows);
	}

	/* =========================
	   VENTAS
	   ========================= */

	private function mov_ventas($fecha)
	{
		[$inicio, $fin] = $this->rango_dia($fecha);

		return $this->db
			->select('pv.id_producto, t.id_almacen')
			->from('productos_ventas pv')
			->join('ventas v', 'v.id = pv.id_venta')
			->join('transportistas t', 't.id = v.id_transportista')
			->group_start()
				// cualquier venta que modifique stock
				->where('v.modified >=', $inicio)
				->where('v.modified <=', $fin)
				->or_group_start()
					->where('pv.modified >=', $inicio)
					->where('pv.modified <=', $fin)
				->group_end()
			->group_end()
			->get()
			->result_array();
	}

	/* =========================
	   TRASPASOS ORIGEN
	   ========================= */

	private function mov_traspasos_origen($fecha)
	{
		[$inicio, $fin] = $this->rango_dia($fecha);

		return $this->db
			->select('pt.id_producto, tr.id_origen AS id_almacen')
			->from('productos_traspasos pt')
			->join('traspasos tr', 'tr.id = pt.id_traspaso')
			->where('tr.deleted', 0)
			->where('pt.deleted', 0)
			->group_start()
				->where('tr.fecha_completado >=', $inicio)
				->where('tr.fecha_completado <=', $fin)
				->or_group_start()
					->where('pt.modified >=', $inicio)
					->where('pt.modified <=', $fin)
				->group_end()
			->group_end()
			->get()
			->result_array();
	}

	/* =========================
	   TRASPASOS DESTINO
	   ========================= */

	private function mov_traspasos_destino($fecha)
	{
		[$inicio, $fin] = $this->rango_dia($fecha);

		return $this->db
			->select('pt.id_producto, tr.id_destino AS id_almacen')
			->from('productos_traspasos pt')
			->join('traspasos tr', 'tr.id = pt.id_traspaso')
			->where('tr.estado_traspaso', 4)
			->where('tr.deleted', 0)
			->where('pt.deleted', 0)
			->group_start()
				->group_start()
					->where('tr.fecha_completado >=', $inicio)
					->where('tr.fecha_completado <=', $fin)
				->group_end()
				->or_group_start()
					->where('pt.modified >=', $inicio)
					->where('pt.modified <=', $fin)
				->group_end()
			->group_end()
			->get()
			->result_array();
	}

	/* =========================
	   COMPRAS
	   ========================= */

	private function mov_compras($fecha)
	{
		[$inicio, $fin] = $this->rango_dia($fecha);

		return $this->db
			->select('cp.id_producto, c.id_almacen')
			->from('compras_productos cp')
			->join('compras c', 'c.id = cp.id_compra')
			->group_start()
				->group_start()
					->where('c.fecha >=', $inicio)
					->where('c.fecha <=', $fin)
				->group_end()
				->or_group_start()
					->where('c.modified >=', $inicio)
					->where('c.modified <=', $fin)
				->group_end()
				->or_group_start()
					->where('cp.modified >=', $inicio)
					->where('cp.modified <=', $fin)
				->group_end()
			->group_end()
			->group_start()
				->where('c.deleted', 0)
				->or_group_start()
					->where('c.deleted', 1)
					->where('c.modified >=', $inicio)
					->where('c.modified <=', $fin)
				->group_end()
			->group_end()
			->group_start()
				->where('cp.deleted', 0)
				->or_group_start()
					->where('cp.deleted', 1)
					->where('cp.modified >=', $inicio)
					->where('cp.modified <=', $fin)
				->group_end()
			->group_end()
			->get()
			->result_array();
	}

	public function get_stock_actual($id_producto, $id_almacen)
	{
		$row = $this->db
			->select('stock, disponibles, reservados, en_transito')
			->from('almacenes_productos')
			->where('id_producto', $id_producto)
			->where('id_almacen', $id_almacen)
			->where('deleted', 0)
			->limit(1)
			->get()
			->row_array();

		// Si no existe registro, asumimos 0 en todos los valores
		return [
			'stock' => $row ? (int)$row['stock'] : 0,
			'disponibles' => $row ? (int)$row['disponibles'] : 0,
			'reservados' => $row ? (int)$row['reservados'] : 0,
			'en_transito' => $row ? (int)$row['en_transito'] : 0
		];
	}

	/* =========================
	   UTILIDADES
	   ========================= */

	private function rango_dia($fecha)
	{
		return [
			$fecha . ' 00:00:00',
			$fecha . ' 23:59:59'
		];
	}

	private function unique(array $rows)
	{
		$out = [];
		$map = [];

		foreach ($rows as $r) {
			$key = $r['id_producto'] . '-' . $r['id_almacen'];
			if (!isset($map[$key])) {
				$map[$key] = true;
				$out[] = $r;
			}
		}

		return $out;
	}
}