<?php
namespace App\Controller;

use Incoviba\old\Venta\Venta;
use Incoviba\old\Venta\Unidad;
use Incoviba\old\Venta\Propiedad;

class Buscar
{
	protected static $tipos = ['cualquiera', 'departamento', 'estacionamiento', 'bodega', 'propietario', 'precio venta', 'proyecto', 'pago', 'unidad'];

	public static function index()
	{
		$results = self::getResults();
		$tipos = self::$tipos;
		return view('buscar.buscar', compact('tipos', 'results'));
	}
	public static function ajax()
	{
		$results = self::getResults();
		return json_encode(['results' => $results]);
	}
	protected static function getResults()
	{
		$q = get('q');
		if ($q == null) {
			$q = get('query');
		}
		$t = get('t');
		if ($t == null) {
			$t = get('tipo');
		}
		$t = urldecode($t);
		if ($t == null) {
			$t = 'cualquiera';
		}

		$results = null;
		if ($q != null) {
			$q = urldecode($q);
			$results = self::buscar($q, $t);
		}
		return $results;
	}
	public static function buscar($query, $tipo)
	{
		$method = 'buscar' . str_replace(' ', '', ucwords($tipo));
		if (is_callable(['self', $method])) {
			$results = self::$method(self::prepareQuery($query));
			$results = self::removeDuplicates($results);
			$results = self::sort($results);
			return $results;
		}
		return [];
	}
	protected static function prepareQuery($query)
	{
		$query = str_replace('&#34;', '"', $query);
		$data = explode(' ', $query);
		$regex = "~(?=\\S)[^'\"\\s]*(?:'[^']*'[^'\"\\s]*|\"[^\"]*\"[^'\"\\s]*)*~";
		preg_match_all($regex, $query, $data);
		$data = $data[0];
		foreach ($data as &$l) {
			$l = str_replace('"', '', str_replace("'", '', $l));
		}
		if (is_array($data) and count($data) == 1) {
			$data = $data[0];
		}
		return $data;
	}
	protected static function removeDuplicates($results)
	{
		$output = [];
		foreach ($results as $result) {
			if (array_search($result, $output) === false) {
				$output []= $result;
			}
		}
		return $output;
	}
	protected static function sort($results)
	{
		usort($results, function($a, $b) {
			$py = strcmp($a->proyecto()->descripcion, $b->proyecto()->descripcion);
			if ($py == 0) {
				if (!method_exists($a, 'unidad') and !method_exists($b, 'unidad')) {
					return $a->descripcion - $b->descripcion;
				}
				if (!method_exists($a, 'unidad')) {
					return $a->descripcion - $b->unidad()->descripcion;
				}
				if (!method_exists($b, 'unidad')) {
					return $a->unidad()->descripcion - $b->descripcion;
				}

				$u = $a->unidad()->descripcion - $b->unidad()->descripcion;
				if ($u == 0) {
					return strcmp($a->propietario()->apellido_paterno, $b->propietario()->apellido_paterno);
				}
				return $u;
			}
			return $py;
		});
		return $results;
	}
	protected static function buscarCualquiera($query)
	{
		$results = [];
		foreach (self::$tipos as $tipo) {
			if ($tipo == 'cualquiera') {
				continue;
			}
			$method = 'buscar' . str_replace(' ', '', ucwords($tipo));

			if (is_callable(['self', $method])) {
				$results = array_merge($results, self::$method($query));
			}
		}
		return $results;
	}
	protected static function buscarDepartamento($query)
	{
		if (is_array($query)) {
			$results = [];
			foreach ($query as $segment) {
				$results = array_merge($results, self::buscarDepartamento($segment));
			}
		} else {
			$results = \Model::factory(Venta::class)
				->select('venta.*')
				->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
				->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
				->whereLike('unidad.descripcion', '%' . $query . '%')
				->findMany();
		}
		return $results;
	}
	protected static function buscarEstacionamiento($query)
	{
		if (is_array($query)) {
			$results = [];
			foreach ($query as $segment) {
				$results = array_merge($results, self::buscarEstacionamiento($segment));
			}
		} else {
			$results = \Model::factory(Venta::class)
				->select('venta.*')
				->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
				->join('unidad', "`propiedad`.`estacionamientos` LIKE `unidad`.`id` OR `propiedad`.`estacionamientos` LIKE CONCAT('%;', `unidad`.`id`) OR `propiedad`.`estacionamientos` LIKE CONCAT(`unidad`.`id`, ';%') OR `propiedad`.`estacionamientos` LIKE CONCAT('%;', `unidad`.`id`, ';%')")
				->where('unidad.descripcion', $query)
				->findMany();
		}
		return $results;
	}
	protected static function buscarBodega($query)
	{
		if (is_array($query)) {
			$results = [];
			foreach ($query as $segment) {
				$results = array_merge($results, self::buscarBodega($segment));
			}
		} else {
			$results = \Model::factory(Venta::class)
				->select('venta.*')
				->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
				->join('unidad', "`propiedad`.`bodegas` LIKE `unidad`.`id` OR `propiedad`.`bodegas` LIKE CONCAT('%;', `unidad`.`id`) OR `propiedad`.`bodegas` LIKE CONCAT(`unidad`.`id`, ';%') OR `propiedad`.`bodegas` LIKE CONCAT('%;', `unidad`.`id`, ';%')")
				->where('unidad.descripcion', $query)
				->findMany();
		}
		return $results;
	}
	protected static function buscarPropietario($query)
	{
		if (is_array($query)) {
			$results = [];
			foreach ($query as $segment) {
				$results = array_merge($results, self::buscarPropietario($segment));
			}
		} else {
			$results = self::buscarPropietarioNombres($query);
			$results = array_merge($results, self::buscarPropietarioApellido($query));
			$results = array_merge($results, self::buscarPropietarioNombreCompleto($query));
		}
		return $results;
	}
	protected static function buscarPropietarioNombres($query)
	{
		$results = \Model::factory(Venta::class)
			->select('venta.*')
			->join('propietario', ['propietario.rut', '=', 'venta.propietario'])
			->whereLike('propietario.nombres', '%' . $query . '%')
			->findMany();
		return $results;
	}
	protected static function buscarPropietarioApellido($query)
	{
		$results = \Model::factory(Venta::class)
			->select('venta.*')
			->join('propietario', ['propietario.rut', '=', 'venta.propietario'])
			->whereAnyIs([
					['propietario.apellido_paterno' => '%' . $query . '%'],
					['propietario.apellido_materno' => '%' . $query . '%']
			], 'LIKE')
			->findMany();
		return $results;
	}
	protected static function buscarPropietarioNombreCompleto($query)
	{
		$results = \Model::factory(Venta::class)
			->select('venta.*')
			->join('propietario', ['propietario.rut', '=', 'venta.propietario'])
			->whereRaw("CONCAT_WS(' ', propietario.nombres, propietario.apellido_paterno, propietario.apellido_materno) LIKE '%" . $query . "%'")
			->findMany();
		return $results;
	}
	protected static function buscarPrecioVenta($query)
	{
		if (is_array($query)) {
			$results = [];
			foreach ($query as $segment) {
				$results = array_merge($results, self::buscarPrecioVenta($segment));
			}
		} else {
			$query = str_replace([',', '.'], ['.', ''], $query);
			$results = \Model::factory(Venta::class)->where('valor_uf', $query)->findMany();
		}
		return $results;
	}
	protected static function buscarProyecto($query)
	{
		if (is_array($query)) {
			$results = [];
			foreach ($query as $segment) {
				$results = array_merge($results, self::buscarProyecto($segment));
			}
		} else {
			$results = model(Venta::class)
				->select('venta.*')
				->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
				->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
				->join('proyecto', ['proyecto.id', '=', 'unidad.proyecto'])
				->whereLike('proyecto.descripcion', '%' . $query . '%')
				->findMany();
		}
		return $results;
	}
	protected static function buscarPago($query)
	{
		if (is_array($query)) {
			$results = [];
			foreach ($query as $segment) {
				$results = array_merge($results, self::buscarPrecioVenta($segment));
			}
		} else {
			$query = str_replace(',', '.', str_replace('.', '', $query));
			$query2 = (float) $query;
			if ($query != $query2) {
				return [];
			}
			if (!is_float($query2)) {
				return [];
			}
			$query = $query2;
			$results = self::buscarValorCuota($query);
			$results = array_merge($results, self::buscarReajuste($query));
			$results = array_merge($results, self::buscarEscritura($query));
			$results = array_merge($results, self::buscarSubsidio($query));
			$results = array_merge($results, self::buscarCredito($query));
		}
		return $results;
	}
	protected static function buscarValorCuota($query)
	{
		$results = \Model::factory(Venta::class)
			->select('venta.*')
			->join('cuota', ['cuota.pie', '=', 'venta.pie'])
			->join('pago', ['pago.id', '=', 'cuota.pago'])
			->whereRaw("`pago`.`valor` = " . $query . " OR `pago`.`valor` / `pago`.`uf` = " . $query)
			->findMany();
		return $results;
	}
	protected static function buscarReajuste($query)
	{
		$results = \Model::factory(Venta::class)
			->select('venta.*')
			->join('pie', ['pie.id', '=', 'venta.pie'])
			->join('pago', ['pago.id', '=', 'pie.reajuste'])
			->whereRaw("`pago`.`valor` = " . $query . " OR `pago`.`valor` / `pago`.`uf` = " . $query)
			->findMany();
		return $results;
	}
	protected static function buscarEscritura($query)
	{
		$results = \Model::factory(Venta::class)
			->select('venta.*')
			->join('escritura', ['escritura.id', '=', 'venta.escritura'])
			->join('pago', ['pago.id', '=', 'escritura.pago'])
			->whereRaw("`pago`.`valor` = " . $query . " OR `pago`.`valor` / `pago`.`uf` = " . $query)
			->findMany();
		return $results;
	}
	protected static function buscarSubsidio($query)
	{
		$results = \Model::factory(Venta::class)
			->select('venta.*')
			->join('subsidio', ['subsidio.id', '=', 'venta.subsidio'])
			->join('pago', ['pago.id', '=', 'subsidio.pago'])
			->whereRaw("`pago`.`valor` = " . $query . " OR `pago`.`valor` / `pago`.`uf` = " . $query)
			->findMany();
		return $results;
	}
	protected static function buscarCredito($query)
	{
		$results = \Model::factory(Venta::class)
			->select('venta.*')
			->join('credito', ['credito.id', '=', 'venta.credito'])
			->join('pago', ['pago.id', '=', 'credito.pago'])
			->whereRaw("`pago`.`valor` = " . $query . " OR `pago`.`valor` / `pago`.`uf` = " . $query)
			->findMany();
		return $results;
	}
	protected static function buscarUnidad($query)
	{
		if (is_array($query)) {
			$results = [];
			foreach ($query as $segment) {
				$results = array_merge($results, self::buscarUnidad($segment));
			}
		} else {
			$results = model(Unidad::class)->where('descripcion', $query)->findMany();
			foreach ($results as $i => $u) {
				if ($u->venta()) {
					unset($results[$i]);
				}
			}
		}
		return $results;
	}
}
?>
