<?php

namespace Garradin\Plugin\Facturation;

use Garradin\DB;
use Garradin\UserException;

class Facture
{
	private $keys = [
		'type_facture',
		'numero',
		'receveur_membre',
		'receveur_id',
		'date_emission',
		'date_echeance',
		'reglee',
		'archivee',
		'moyen_paiement',
		'contenu',
		'total'
	];

	public function __construct()
	{

	}

	public function _checkFields(&$datas)
	{
		foreach($datas as $k=>$data)
		{
			if (!in_array($k, $this->keys))
			{
				throw new UserException("Clé inattendue : $k.");
			}

			if(!is_array($data)){
				$datas[$k] = trim($data);
			}
			if ($datas[$k] === '')
			{
				throw new UserException("La valeur de $k est vide");
			}


			switch($k)
			{
			case 'type_facture':
			case 'receveur_membre':
			case 'reglee':
			case 'archivee':
				if ($datas[$k] != 1 && $datas[$k] != 0)
				{
					throw new UserException("$k est de valeur non-attendue ($data).");
					}
					break;
case 'receveur_id':
	if (!is_numeric($datas[$k]) || $datas[$k] < 0 )
	{
		throw new UserException("L'id du receveur est non-attendu ($data).");
					}
					break;
case 'date_emission':
	if (!strtotime($datas[$k]))
	{
		throw new UserException("La date d'émission est non-attendue ($data).");
					}
					break;
case 'date_echeance':
	if (!strtotime($datas[$k]))
	{
		throw new UserException("La date d'émission est non-attendue ($data).");
					}
					if (isset($datas['date_emission']) && (strtotime($datas[$k]) <= strtotime($datas['date_emission']) ) )
					{
						throw new UserException("La date d'échéance est antérieure ou égale à la date d'émission ($data).");
					}
					break;
case 'moyen_paiement':
	$cats = new \Garradin\Compta\Categories;
	if(!array_key_exists($datas[$k], $cats->listMoyensPaiement()))
	{
		throw new UserException("Le moyen de paiement ne correspond pas à la liste interne ($data).");
					}
					unset($cats);
					break;
case 'contenu':
	if(!is_array($datas[$k]) || empty($datas[$k]))
	{
		throw new UserException("Le contenu du document est vide ($data).");
					}
					$total = 0;
					$vide = 1;
					foreach($datas[$k] as $g=>$r)
					{
						if ($r['designation'] !== '' && is_numeric($r['prix']))
						{
							$vide = 0;
						}
						else
						{
							unset($datas[$k][$g]);
						}
						$total += $r['prix']; 
					}
					if($vide)
					{
						throw new UserException("Toutes les désignations/prix sont vides.");
					}
					$datas[$k] = serialize($datas[$k]);
					break;
case 'total':
	if(!isset($datas['contenu']))
	{
		throw new UserException("Pas de contenu fourni pour vérifier le total.");
					}
					if ($total != $datas[$k])
					{
						throw new UserException("Les totaux sont différents ($total != $datas[$k].");
					} 
					break;
			}
		}
	}

	public function add($data)
	{
		$db = DB::getInstance();

		$this->_checkFields($data);

		if(isset($data['numero']) && $db->test('plugin_facturation_factures', 'numero = ? COLLATE NOCASE', $data['numero']))
		{
			throw new UserException('Une facture avec ce numéro existe déjà, hors le numéro doit être unique.');
		}
		$db->insert('plugin_facturation_factures', $data);
		return $db->lastInsertRowId();		
	}

	public function get($id)
	{
		$db = DB::getInstance();

		$r = $db->first('SELECT *, strftime(\'%s\', date_emission) AS date_emission,
			strftime(\'%s\', date_echeance) AS date_echeance
			FROM plugin_facturation_factures WHERE id = ? LIMIT 1;', (int)$id);

		if(!$r)
		{	
			throw new UserException("Pas de facture retournée avec cet id.");
		}

		$r->contenu = unserialize($r->contenu);

		return $r;
	}

	public function listAll()
	{
		$r = (array)DB::getInstance()->get('SELECT *, strftime(\'%s\', date_emission) AS date_emission,
			strftime(\'%s\', date_echeance) AS date_echeance
			FROM plugin_facturation_factures');

		foreach ($r as $e)
		{
			$e->contenu = unserialize((string)$e->contenu);
		}

		return $r;
	}

	public function edit($id, $data = [])
	{
		$db = DB::getInstance();

		$this->_checkFields($data);

		if(isset($data['numero']) && $db->test('plugin_facturation_factures', 'numero = ? COLLATE NOCASE AND id != ?', $data['numero'], (int)$id))
		{
			throw new UserException('Une facture avec ce numéro existe déjà, hors le numéro doit être unique.');
		}
		return $db->update('plugin_facturation_factures', $data, $db->where('id', (int)$id));
	}

	public function listUserDoc($base = 0, $id)
	{
		$client = new Client;

		if ($base == 0)
		{
			if(!$client->get($id))
			{
				throw new UserException("Ce client n'existe pas.");
			}
		}
		else
		{
			throw new UserException("Woopsie, g pô encore implémenté l'usage des membres de l'asso comme clients");
		}

		$r = (array)DB::getInstance()->get('SELECT *, strftime(\'%s\', date_emission) AS date_emission,
			strftime(\'%s\', date_echeance) AS date_echeance
			FROM plugin_facturation_factures
			WHERE receveur_membre = ? AND receveur_id = ?', (int)$base, (int)$id);

		foreach ($r as $e)
		{
			$e->contenu = unserialize((string)$e->contenu);
		}

		return empty($r)?false:$r;
	}

	public function hasDocs($base = 0, $id)
	{
		$client = new Client;

		if ($base == 0)
		{
			if(!$client->get($id))
			{
				throw new UserException("Ce client n'existe pas.");
			}
		}
		else
		{
			throw new UserException("Woopsie, g pô encore implémenté l'usage des membres de l'asso comme clients");
		}

		return DB::getInstance()->test('plugin_facturation_factures', 'receveur_membre = '. $base .' AND receveur_id = '. $id);
	}

}
