<?php

class InvoicesController extends \BaseController {

	/**
	 * Display a listing of the resource.
	 * GET /invoices
	 *
	 * @return Response
	 */
	public function index()
	{
		if(!UserRole::has('list_invoice')) return Redirect::route('dashboard');
				$invoices = DB::table('invoices as i')
											->select('i.id', 'i.total', 'i.recieved', 'c.first_name', 'c.last_name', 'c.tel', 'c.id as c_id', 'i.created_at')
											->leftJoin('customers as c', 'c.id', '=', 'i.customer_id')
											->where('i.status', 'closed')
                      ->whereNull('i.referral_id');
        $name = Input::get('name');
        $pattern = "%".$name."%";

				//$data = [];
				//preg_match_all('/./u', $name, $data);
        //$customer = Customer::where('first_name', "LIKE", "%".."%");
        // if (count($data[0]) > 0) {
        // 	$invoices->where(function ($query) use ($data, $name) {
        // 		foreach ($data[0] as $letter) {
        // 			$query->orWhere('c.first_name', "LIKE", "%".$letter."%");
        // 			$query->orWhere('c.last_name', "LIKE", "%".$letter."%");
        // 		}
        // 		$query->orWhere('c.tel', $name);
        // 	});     	
        // }
        if (!empty($name)) {
        	$invoices->where(function ($query) use ($pattern) {
        		$query->where('c.first_name', 'LIKE', $pattern)
        					->orWhere('c.last_name', 'LIKE', $pattern);
        	});
        }
        if (!empty(Input::get('invoice_id'))) {
          $invoices->where('i.id', Input::get('invoice_id'));
        }
        if (!empty(Input::get('start_date')) && !empty(Input::get('end_date'))) {
          $start = new \Carbon\Carbon(Input::get('start_date'));
    			$end = new \Carbon\Carbon(Input::get('end_date'));
    			$end->addHours(23)->addMinutes(59)->addSeconds(59);
          $invoices->whereBetween('i.created_at', [$start, $end]);
        }

        if (!empty(Input::get('type'))) {
          $type = Input::get('type');
          if ($type == "deposit") {
            $invoices->whereNotNull('c.id')->where('deposit', '>', 0);
          }
        }
	   		return View::make('Invoices.index')->withInvoices($invoices->orderBy('id', 'DESC')->paginate(10));
	}

	/**
	 * Show the form for creating a new resource.
	 * GET /invoices/create
	 *
	 * @return Response
	 */
	public function create()
	{
		//
	}

	/**
	 * Store a newly created resource in storage.
	 * POST /invoices
	 *
	 * @return Response
	 */
	public function store()
	{
		//
	}

	/**
	 * Display the specified resource.
	 * GET /invoices/{id}
	 *
	 * @param  int  $id
	 * @return Response
	 */
	public function show($id)
	{
		if(!UserRole::has('detail_invoice')) return Redirect::route('dashboard');
		/**
		 * Default View
		 */
		$view = View::make('Invoices.show');

		$invoice = Invoice::find($id);
		if (empty($invoice)) return Redirect::route('invoices.index');
		// get product related with invoice
		$products = Invoice::getProductsWithInvoiceId($id);
		$customer = Customer::find($invoice->customer_id);
		if (empty($customer)) {
			$view->withInvoice($invoice)->withProducts($products);
		} else {
			$payables = Payable::where('invoice_id', $id)->get();
			$view->with('payables', $payables)
					 ->withCustomer($customer)
					 ->withProducts($products)
					 ->withInvoice($invoice);
		}
		return $view;
	}

	/**
	 * Show the form for editing the specified resource.
	 * GET /invoices/{id}/edit
	 *
	 * @param  int  $id
	 * @return Response
	 */
	public function edit($id)
	{
		//
	}

	/**
	 * Update the specified resource in storage.
	 * PUT /invoices/{id}
	 *
	 * @param  int  $id
	 * @return Response
	 */
	public function update($id)
	{
		//
	}

	/**
	 * Remove the specified resource from storage.
	 * DELETE /invoices/{id}
	 *
	 * @param  int  $id
	 * @return Response
	 */
	public function destroy($id)
	{
		//
	}
	/**
	 * [checkout description]
	 */
	public function checkout()
	{
		/* Check if user saves invoice*/
		$invoiceId = InvoiceHelper::getInvoiceID();
		if(Input::get('save')) {
			$customer = (!empty(Input::get('select-customer'))) ? Input::get('select-customer') : null;
			InvoiceHelper::suspendInvoice($customer);
			return Redirect::back();
		}
		/* Check if user wants to checkout*/                                              
		else {
			$success = false;
			DB::beginTransaction();
			$customer = (!empty(Input::get('select-customer'))) ? Input::get('select-customer') : '';
			$stockId = Auth::user()->stock_id;
			$cart_items = DB::table('Orders')->where('invoice_id', $invoiceId)->get();

			foreach ($cart_items as $item){
				$amount = $item->amount;
				$productId = $item->product_id;
				$item_instock = DB::table('Outlets')->join('Products','Products.id','=','Outlets.product_id')->where(function ($query) use ($productId,$stockId) {
					$query->where('Outlets.product_id', $productId)
							->where('Outlets.stock_id', '=',$stockId);
				})->select(['Outlets.*','Products.id as pid','Products.is_service'])->first();
				/*
				Check if the product is service, then don't deduct from stock
				 */
				if($item_instock->is_service == false):
					$outlet = Outlet::find($item_instock->id);
					$outlet->amount = ($amount >= $item_instock->amount) ? 0 : $item_instock->amount - $amount;
					$outlet->on_hold = ($amount > $item_instock->amount ) ? ($amount - $item_instock->amount) : $item_instock->on_hold - $amount;
					$outlet->save();
				endif;
				DB::table('Orders')
						->where('invoice_id',$invoiceId)
						->update(array('sold' =>'1'));
			}
			$totalReceive = Input::get('input-dollar')+(Input::get('input-riel')/Helper::getConfig('invoice_rate'));
			$deposit =  InvoiceHelper::calculateTax()-$totalReceive;
			$change  = $totalReceive-InvoiceHelper::calculateTax();
			$updateinvoice = Invoice::find($invoiceId);
			$updateinvoice->recieved = $totalReceive;

			if($deposit>0) {
				$updateinvoice->deposit = $deposit;
			}
			if($change>0) {
				$updateinvoice->changed  = $change;
			}
			$updateinvoice->customer_id = $customer;
			$updateinvoice->status = 'closed';
			if ($totalReceive > 0) {
				$updateinvoice->recieved_dollar = Input::get('input-dollar');
				$updateinvoice->recieved_riel = Input::get('input-riel');
			}
			if($updateinvoice->save()){
				Session::put('invoiceToPrint', $invoiceId);

				$income = new Profit;
				$income->amount = $change > 0 ? $totalReceive-$change : $totalReceive;
				$income->user_id = Auth::user()->id;
				$income->invoice_id = $updateinvoice->id;
				$income->type = 'income';
				$income->rate = $updateinvoice->rate;
				if($income->save()) {
					$success = true;
				}
			}
			if (!$success) {
          DB::rollback();
          return Redirect::back()->withInput()->with('message','messages.fail-to-create')->with('messageType','danger');
      } else {
      	DB::commit();
      	if(Input::get('print-invoice') == "on") {
      		$invoiceUrl = route('printinvoice');
      		$saleUrl = route('sale');
      		return '
						<script type="text/javascript">
							window.open("'.$invoiceUrl.'", "_blank");
							window.location = "'.$saleUrl.'";
						</script>
					';
      	}
      	else {
      		return Redirect::back()->withInput()->with('message','messages.success-to-create')->with('messageType','success');
      	}

      }


		}
		return Redirect::back();
	}
	public function suspend()
	{
		InvoiceHelper::suspendInvoice();
		return Redirect::back();
	}
	public function switchInvoice($id)
	{
		InvoiceHelper::switchInvoice($id);
		return Redirect::back();
	}

	/**
	 * Print Invoice
	 * @return Mixed Object [description]
	 * @todo  Replace Session
	 */
	public function printinvoice($id = NULL)
	{
		// $invoiceI = Invoice::first();
		$invoiceId = ($id) ? $id : Session::get('invoiceToPrint');
    $invoice = DB::table('invoices as i')
              ->join('users as u', 'u.id', '=', 'i.user_id')
              ->leftJoin("customers as c", "c.id", '=', 'i.customer_id')
              ->select(
                'c.first_name',
                'c.last_name',
                'c.tel',
                'c.address',
                'u.first_name as funame',
                'u.last_name as luname',
                'i.*'
              )->where('i.id', $invoiceId)->first();
	    if (empty($invoice)) return App::abort(404, 'No Invoice Found');
	    $orders = DB::table('products as p')
	                ->join('orders as o', 'o.product_id', '=', 'p.id')
	                ->leftJoin('units as u', 'u.id', '=', 'p.unit_id')
	                ->select(
	                	'o.sku',
	                  'p.name',
	                  'o.price',
	                  'o.amount',
	                  'u.name as unit'
	                )->where('o.invoice_id', $invoiceId)->get();		

		$products = DB::table('products as p')
									->join('buy_products as bp', 'bp.product_id', '=', 'p.id')
									->select('p.id','p.sku', 'p.name', 'bp.qty', 'bp.price', 'bp.id as bp_id')
									->where('bp.invoice_id', $invoiceId)
									->get();
		$printerType = (Helper::getConfig('invoice_type')=="terminal-printer") ? "v1" : "npc2";

		return View::make('invoices.invoice.'.$printerType)->with('title','Invoice Printing')
				->with('invoice',$invoice)
				->with('orders',$orders);
	}
	public function postDeposit()
	{
        $invoiceId = (int) Input::get("invoice_id");
        $payable   = (float) Input::get('payable');
        $note      = !empty(Input::get('note')) ? Input::get('note') : trans('invoices.customer_payable');
        $invoice = Invoice::find($invoiceId);
        // Invoice doesn't exist redirect back
        if (empty($invoice)) return Redirect::back();
        $min_payment = (float) round((get_min_return()/100) * $invoice->deposit);
        if ($payable < $min_payment) return Redirect::back()->withInput()
                                      ->withMessage(trans("invoices.min_payment", ['attribute' => money($min_payment)]))
                                      ->with("messageType", 'danger');
    		DB::beginTransaction();
    		try {
    			// create new invoice
    			$new_payable = new Payable();
    			$new_payable->amount = (float) $payable;
    			$new_payable->user_id = Auth::user()->id;
    			$new_payable->invoice_id = $invoiceId;
          $new_payable->note        = $note;
          $new_payable->deposit     = $invoice->deposit;
    			// create new profits
    			$income = new Profit;
    			$income->user_id = Auth::user()->id;
    			$income->type = 'income';
    			$income->rate = $invoice->rate;
          if ($payable >= $invoice->deposit) {
            $new_payable->changed = $payable - $invoice->deposit;
            $income->amount = $invoice->deposit;
            $invoice->deposit = 0;
          } else {
            $income->amount = $payable;
            $invoice->deposit -= $payable;
          }
          if ($invoice->save() && $new_payable->save() && $income->save()) {
            DB::commit();
            return Redirect::back()->withMessage(trans('invoices.payment_success'))
                           ->with("messageType", 'success');
          } else {
            DB::rollback();
            return Redirect::back()->withMessage(trans('invoices.payment_fail'))
                           ->with("messageType", 'danger');

          }
		} catch (Exception $e) {
			DB::rollback();
			return dd($e->getMessage());
            return Redirect::back()->withMessage(trans('invoices.payment_fail'))
                           ->with("messageType", 'danger');
		}
	}
	
	/**
	 * Get Draft Invoices
	 * @return [type] [description]
	 */
	public function draftInvoices()
	{
		if(!UserRole::has('delete_draft_invoice')) return Redirect::route('dashboard');
		$invoices = Invoice::where('status', 'draft')
											 ->where('total', 0)
											 ->get();
		return View::make('Invoices.draft')
							 ->withInvoices($invoices);
	}
	public function deleteDraftInvoices()
	{
		$invoiceID = [];
		$invoices = Invoice::where('status', 'draft')
											 ->where('total', 0)
											 ->get();
		foreach ($invoices as $invoice) {
			$invoiceID[] = $invoice->id;
		}
		if(Invoice::destroy($invoiceID)) {
			return Redirect::back()
										 ->withMessage('messages.success-to-delete')
										 ->with('messageType', "success");
		}else {
			return Redirect::back()
										 ->withMessage('messages.fail-to-delete')
										 ->with('messageType', "danger");
		}
	}
	public function deleteDraftInvoice($id)
	{
		$invoice = Invoice::destroy($id);
		if($invoice) {
			return Redirect::back()
										 ->withMessage('messages.success-to-delete')
										 ->with('messageType', "success");
		} else {
			return Redirect::back()
										 ->withMessage('messages.fail-to-delete')
										 ->with('messageType', "danger");
		}
	}
	public function getExpiredInvoices()
	{
		$invoices = Invoice::getExpiredInvoices();
		return View::make('Invoices.late_payable')->withInvoices($invoices);
	}

	public function cancelInvoice()
	{
		if (!UserRole::has('delete_invoice')) return Redirect::route('dashboard');
		$search = (int) Input::get('search');
		$view = View::make('invoices.delete_invoice');
		if(!empty($search)) {
			$invoice = Invoice::where('id', $search)
								->where('status', 'closed')
								->first();
			if(!empty($invoice)) {
				$orders = Order::where("invoice_id", $invoice->id)
                                ->where('sold', 1)->get();
				$view->withInvoice($invoice)
				->withOrders($orders);
			}

		}
		return $view;

	}
    public function deleteCancelInvoice($id)
    {
        $orders = Order::where('invoice_id', $id)->get();
        foreach ($orders as $order) {
            $outlet = Outlet::where('product_id', $order->product_id)->first();
            $outlet->amount += $order->amount;
            $outlet->available_amount = $outlet->amount;
            $outlet->save();
        }
        $invoice = Invoice::find($id);
        $profit = Profit::where('invoice_id', $id)->first();
        $profit = $profit->delete();
        $invoice = $invoice->delete();
        if($invoice && $invoice) return Redirect::route('invoices.index')
                        ->withMessage('messages.success-to-delete')
                        ->with('messageType', 'success');
        return Redirect::route('getDeleteInvoice')
                    ->withMessage('messages.fail-to-delete')
                    ->with('messageType', 'danger');
    }
}
