<?php

namespace App\Controllers;
use App\Models\mBills;
use App\Models\mAccounts;
use CodeIgniter\Session\Session;
use CodeIgniter\Files\File;
use CodeIgniter\I18n\Time;

class Home extends BaseController
{

    private $accounts;
	/**
	 * @var Session
	 */
	protected $session;
	
	public function __construct()
	{
		$this->session = service('session');
		$this->accounts = model('App\Models\mAccounts');
	}

    public function overview()
    {
        return view('table');
    }

	private function checkDDPList(&$arr, $ele){
		
		if (!array_key_exists($ele, $arr)){
			$arr[$ele] = $this->accounts->getDropDownEntry($ele);
		}
	}

	private function checkDDSList($arr, $par, $ele){
		if (!array_key_exists($par, $arr)){
			$ret = array();
			if ($ele > 0)
				$ret[$ele] = $this->accounts->getDropDownEntry($ele);
			else
				$ret[0] = '-----';
			return $ret;
		}	
		else{
			return $arr[$par];
		}

	}

	private function loadFormDefaults(){
		$data['id'] = 0;
		$data['source'] = 0;
		$data['datum'] ='';
		$data['renummer'] = false;
		$data['multi'] = false;
		$data['transfer'] = false;
		$data['receiver'] = '';
		$data['total_in'] = '';
		$data['total_out'] = '';
		$data['validate'] = false;
		$data['scheduled'] = false;
		$data['scheduledNum'] = 0;
		$data['scheduledType'] = 0;
		for ($i=0;$i<10;$i++){
			$data['sid'][$i] = 0;
			$data['category_parent'][$i] = 0;
			$data['category'][$i] = 0;
			$data['input'][$i] = '';
			$data['output'][$i] = '';
			$data['comment'][$i] = '';
		}
		return $data;
	}

	/**
	 * Legt eine neue Terminbuchung an
	 * @param bool $transfer ob Terminbuchung vom Typ Transfer ist
	 * @return char gibt die View zurück
	**/
	public function newScheduled($transfer = 0){
		$data = $this->loadFormDefaults();
		$data['transfer'] = (bool)$transfer;
		return $this->newBill($data,NULL,true);
	}

	public function newTransfer(){
		$data = $this->loadFormDefaults();
		$data['transfer'] = true;
		return $this->newBill($data,NULL);
	}

    public function newBill($data = NULL, $errors = NULL,$scheduled = false){
		helper('form');
		$data = $data ?? $this->loadFormDefaults();
		$data['isScheduled'] = $scheduled;
		$data['validation'] = $errors;
		
		$srclist = $this->accounts->getDropDownList( 'Acc', TRUE );
		$this->checkDDPList($srclist,$data['source']);
		$data['sourcelist'] =  $srclist;
		$data['scheduled'] = array('NumList' => array('1'=>'1','2'=>'2','3'=>'3','4'=>'4','5'=>'5','6'=>'6'),
								'TypeList' => array('week'=>'Woche(n)','month'=>'Monat(e)','year'=>'Jahr(e)'),
								'style' => 'class="form-select"');
		if ($data['transfer'])
			$categories = $this->accounts->getDropDownLists( 'Acc', TRUE );
		else	
			$categories = $this->accounts->getDropDownLists( 'InOut', TRUE );
			
		// $data['catparentlist'] = $categories['parent'];
		// if (!array_key_exists('catparent', $data))
		// 	$data['catparent'] = $this->accounts->getParent($data['cat']);
		// $this->checkDDPList($data['catparentlist'],$data['catparent']);

		// $data['catlist'] = $this->checkDDSList((array)$categories['subs'],$data['catparent'],$data['cat']);

		$data['subsparent'] = array();
		$data['subscategory'] = array();
		for ($i=0;$i<10;$i++){
			$data['subsparent'][$i] = $categories['parent'];
			$data['category_parent'][$i] = $data['category_parent'][$i] ?? 0;
			$this->checkDDPList($data['subsparent'][$i],$data['category_parent'][$i]);
			$data['subscategory'][$i] = $this->checkDDSList((array)$categories['subs'],$data['category_parent'][$i],$data['category'][$i]??0);			
		}
		$data['subsdata'] = json_encode($categories['subs']);
        return view('newBill', $data);
    }
  
	private function customValidation(&$errors){
		$result = true;
//		if ( "on" == $this->request->getPost('multi') )
//		{
			for ($i=0;$i<10;$i++){
				$inp = $this->request->getPost("input[$i]");
				$outp = $this->request->getPost("output[$i]");
				$cat = $this->request->getPost("category[$i]");
				if ((is_numeric($inp) && $inp > 0.0)  || (is_numeric($outp) && $outp > 0.0)){
					if ($cat == 0){
						$result &= false;
						$errors['Kategorie']="Kategorie [$i] fehlt oder ungültig";
					}
				}
				if ($cat > 0){
					$errors['log2'] = "cat recognized";
					if (!((is_numeric($inp) && ($inp > 0.0))  || (is_numeric($outp) && ($outp > 0.0)))){
						$errors['Betrag']="Betrag [$i] fehlt oder ungültig";
						$result &= false;
					}
				}
			}
//		}
		// else{
		// 	if ((is_numeric($this->request->getPost('total_in')) && $this->request->getPost('total_in') > 0.0)  || (is_numeric($this->request->getPost('total_out')) && $this->request->getPost('total_out') > 0.0)){
		// 	return true;
		// 	}
		// 	else
		// 	 $errors['Betrag']="Betrag fehlt oder ungültig";
		// }
		return $result;
	}

	public function viewBill(string $filename) {
		$filePath= WRITEPATH . '/uploads';
		$file = new \CodeIgniter\Files\File($filePath."/".$filename);
		log_message('debug',$file->getMimeType());
		if ($file->getMimeType() == 'application/pdf')
			$this->viewPdf($filename);
		else{
			$imginfo = getimagesize($filePath."/".$filename);
			header("Content-type: {$imginfo['mime']}");
			readfile($filePath."/".$filename);
			exit;
		}
//			return view('viewBillImg', ['filename'=>'writable/uploads/'.$filename]);
	}
	
	
	public function viewPdf(string $filename) {
        $view = \Config\Services::renderer();
        log_message('debug',$filename);
        $filePath= WRITEPATH . '/uploads';
        header("Cache-Control: maxage=1");
        header("Pragma: public");
        header('Content-type:application/pdf');
        header('Content-disposition: inline; filename="'.$filename.'"');
        header('content-Transfer-Encoding:binary');
        header('Content-Length:' .filesize($filePath."/".$filename));
        if (($pdf =file_get_contents($filePath."/".$filename)) === false)
            print $filePath."/".$filename;
        else
            print $pdf;
        exit;
    }

	public function attemptNewBilling()
	{
		helper('form');
		$uploading = false;
		$rules = [
			'source' => 'required|greater_than[0]',
			'datum' => 'required',
			'category.0' => 'required|greater_than[0]'
//			'totalamount'=>'required|numeric'
		];
		$errors = [   // Errors
			'source' => ['required' => 'Konto fehlt','greater_than' => 'Konto fehlt'],
			'datum' => ['required' => 'Datum fehlt']];
//			'totalamount' => ['required' => 'Betrag fehlt','numeric' => 'Betrag muss eine Zahl sein']];
		if ( 'on' == $this->request->getPost('multi') ) {
			$rules['openamount'] = 'equals[0]';
			$errors['openamount'] = ['equals' => 'Betrag muss 0 sein'];
		}
		$fehler= array();
		$valid = $this->customValidation($fehler);
		$file = $this->request->getFile('billfile');
		if ($file) {
			if (! $file->isValid() && ($file->getError() != UPLOAD_ERR_NO_FILE)) {
				throw new \RuntimeException($file->getErrorString() . '(' . $file->getError() . ')');
			} else if ($file->isValid()) {
				$rules['billfile'] = ['uploaded[billfile]','max_size[billfile,10000]','mime_in[billfile,application/pdf,image/jpg,image/jpeg]'];
				$errors['billfile'] = ['uploaded'=>'Fehler beim Upload','max_size' => 'Zu Groß', 'mime_in' => "Ungültiger Datentyp"];
				$uploading = true;
			}
		}
		if ((! $this->validate($rules,$errors)) || (!$valid)){
			return $this->newBill($this->request->getPost(), array_merge($this->validator->getErrors(),$fehler),$this->request->getPost('scheduled'));
//			return redirect()->back()->withInput()->with('errors', $validation->getErrors());
		}
		else{
			$data = $this->request->getPost();
			log_message('debug',print_r($data,true));
			
			if ($this->request->getPost('scheduled') =="0"){
				$bills = model('App\Models\mBills');	
				if ($this->request->getPost('removeBillFile')){
					$bills->deleteBillFile($data['id']);
					unlink(WRITEPATH . 'uploads/'.$this->request->getPost('removeBillFile'));
				}
				$billId = $bills->saveBill($data);
				
				if ($uploading){
					$date = Time::parse($data['datum']);		
					$file->move(WRITEPATH . 'uploads',$date->toLocalizedString('yyyyMMdd')." ".$data['receiver']." ".$billId.".".$file->guessExtension());
					log_message('debug', $file->getName());
					$bills->storeBillFile($billId, $file->getName());
				}

				$redirectURL = session('redirect_url') ?? site_url('/');
				unset($_SESSION['redirect_url']);
				return redirect()->to($redirectURL);
			}
			else{
				$scheduled = model('App\Models\mScheduled');
				$scheduled->saveBill($data);
			}
			$this->response->redirect(site_url('/'));
		}
	}

	public function editBill($id){
		$bills = model('App\Models\mBills');
		$data = $this->loadFormDefaults();
        $result = $bills->getEntry($id, $data, $this->accounts);
		return $this->newBill($result);
	}

	public function editScheduled($id){
		$scheduled = model('App\Models\mScheduled');
        $entry = $scheduled->getEntry($id);
		// $bill = array_merge($this->loadFormDefaults(),(array)json_decode($entry['data']));
		// $bill['datum'] = $entry['next_date'];
		return $this->newBill($entry,NULL,true);
	}

	public function deleteScheduled($id){
		$scheduled = model('App\Models\mScheduled');
        $entry = $scheduled->getEntry($id);
		// $bill = array_merge($this->loadFormDefaults(),(array)json_decode($entry['data']));
		// $bill['datum'] = $entry['next_date'];
		return $this->newBill($entry,NULL,true);
	}

	public function syncScheduled(){
		if (!$this->request->isAJAX()) return;
		$scheduled = model('App\Models\mScheduled');
		$schedules = $scheduled->findAll();
		$result = array();
		$line = "";
		foreach ( $schedules as $schedule )
		{
			$cur_date = $schedule['next_date'];
			while ( strtotime( $cur_date ) <= strtotime( "now" ) )
			{
				$line .= " $cur_date - ";
				$bill = array_merge($this->loadFormDefaults(),(array)json_decode($schedule['data']));
				//echo "Hugo:".$schedule['id'];
				$bill['id']=0; // to generate a new booking
				$bill['datum'] = $cur_date;
				$bill['type'] = $bill['transfer']?'transfer':'multiple';
				$line .=  $bill['receiver'];
				$bills = model('App\Models\mBills');
				$bills->saveBill($bill);
				$cur_date = $scheduled->calcNextDate( $cur_date, $bill['scheduledNum'], $bill['scheduledType']);
				$line .= " - $cur_date <br/>";
				//log_message('debug','BudgetScheduled:process data: '.logArray($booking->getData()));
				$scheduled->update($schedule['id'], ['next_date'=>$cur_date ]);
				
			}
		}
		return $line;
		//$this->showTableBookings();
	}

	public function viewAccountsTree(){
		helper('form');
		$data = $this->accounts->getTreeData();
		$data['ddlist'] = $this->accounts->getDropDownList( 'all', false,true );
		return view('accountstree',$data);
		}

	public function attemptEditAccount(){
		$rules = [
			'description'	=> 'required',
			'type' => 'required',
		];
		if (! $this->validate($rules))
		{
			return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
		}
		$this->accounts->saveAccount($this->request->getPost());
//		$this->accounts = model('App\Models\mAccounts', false);
		return $this->viewAccountsTree();

	}

	public function viewAccountActivities(){
		helper('form');
		$data = array();
		$data['source'] = 0;
		$data['start'] =  session('datum_start') ?? date("d.m.Y", strtotime( "- 2 weeks", strtotime( "now" ) ));
		$data['ende'] = session('datum_ende') ?? date("d.m.Y", strtotime( "now" ) );
		$data['source'] = session('source') ?? 0;
		$data['sourcelist'] =  $this->accounts->getDropDownList( 'all', TRUE );
        return view('activities', $data);		
	}

	public function viewScheduled(){
		helper('form');
        return view('scheduled');		
	}
}
