<?php

namespace App\Http\Controllers\v1;

use Illuminate\Http\Request;
use App\Invoice;
use App\WorkOrderVisit;
use App\WorkOrder;
use App\Customer;
use App\Property;
use App\Service;
use App\Product;
use Illuminate\Support\Facades\Mail;

class InvoiceController extends Controller
{
	
	public function index(Request $request)
    {
		
		$invoices = Invoice::with(['work_order', 'customer'])
								->where('company_id', $this->_getCompany()->id);
		
		if (isset($request->date_from) && $request->date_from) {
			$invoices->where('date', '>=', $request->date_from);
		}
		
		if (isset($request->date_to) && $request->date_to) {
			$invoices->where('date', '<=', $request->date_to);
		}
		
		if (!isset($request->date_from) && !isset($request->date_to)) {
			$invoices->where('date', date('Y-m-d'));
		}
		
		$invoices = $invoices->orderBy('date', 'desc')->get();

        return response()->json($invoices, 200);
		
    }
	
	public function show($id)
    {

		$invoice = Invoice::with(['customer', 'property', 'work_order'])->find($id);

		if (!$invoice || $invoice->company_id != $this->_getCompany()->id) {
			return response()->json([
				'title' => 'Invoice',
				'message' => 'Record not found'
			], 404);
		}

		return response()->json($invoice, 200);
	
    }
	
	public function destroy($id)
    {

        $invoice = Invoice::find($id);

        if (!$invoice || $invoice->company_id != $this->_getCompany()->id) {
            return response()->json([
				'title' => 'Invoice',
                'message' => 'Record not found',
            ], 404);
        }
		
		if ($invoice->status_formatted == 'Canceled') {
			
			if (!$invoice->delete()) {
				return response()->json([
					'title' => 'Invoice',
					'message' => 'It was not possible to delete the invoice.'
				], 500);
			}
		
			if ($invoice->quickbooks_id && $this->_hasQuickbooks()) {
				
				$quickbooks = new Quickbooks();
			
				if ($quickbooks->getInvoice($invoice->quickbooks_id)) {
					$quickbooks->deleteInvoice($invoice->quickbooks_id);
				}
				
			}
		
		}
		
		return response()->json([
				'title' => 'Invoice',
				'message' => 'Invoice was deleted successfully.'
			], 200);
	
    }
	
	public function cancel(Request $request, $id)
	{
		
		$invoice = Invoice::find($id);
		
		if (!$invoice || $invoice->company_id != $this->_getCompany()->id) {
			return response()->json([
				'title' => 'Invoice',
				'message' => 'Record not found',
			], 404);
		}
		
		$invoice->updated_at = date('Y-m-d H:i:s');
		$invoice->status = 2;
		
		if (!$invoice->save()) {
			return response()->json([
				'title' => 'Invoice',
				'message' => 'It was not possible to cancel the Invoice.'
			], 500);
		}
		
		if ($invoice->quickbooks_id && $this->_hasQuickbooks()) {
			
			$quickbooks = new Quickbooks();
			
			if ($quickbooks->getInvoice($invoice->quickbooks_id)) {
				$quickbooks->voidInvoice($invoice->quickbooks_id);
			}
			
		}
		
		$customer = Customer::find($invoice->customer_id);
		
		if ($customer) {
			$customer->billed = $customer->billed - $invoice->amount;
			$customer->balance = $customer->balance - $invoice->amount;
			$customer->save();
		}
		
		return response()->json([
			'title' => 'Invoice',
			'message' => 'Invoice was canceled successfully.',
			'object' => $invoice
		], 201);
		
	}
	
	public function confirm(Request $request, $id)
	{
		
		$invoice = Invoice::find($id);
		
		if (!$invoice || $invoice->company_id != $this->_getCompany()->id) {
			return response()->json([
				'title' => 'Invoice',
				'message' => 'Record not found',
			], 404);
		}
		
		$invoice->updated_at = date('Y-m-d H:i:s');
		$invoice->date_paid = date('Y-m-d');
		$invoice->status = 1;
		
		if (!$invoice->save()) {
			return response()->json([
				'title' => 'Invoice',
				'message' => 'It was not possible to confirm the Payment.'
			], 500);
		}
		
		if ($invoice->quickbooks_id && $this->_hasQuickbooks()) {
			
			$quickbooks = new Quickbooks();
		
			if ($quickbooks->getInvoice($invoice->quickbooks_id)) {
				$quickbooks->addPayment($invoice);
			}
			
		}
		
		$customer = Customer::find($invoice->customer_id);
		
		if ($customer) {
			$customer->billed = $customer->billed - $invoice->amount;
			$customer->paid = $customer->paid + $invoice->amount;
			$customer->balance = $customer->balance - $invoice->amount;
			$customer->save();
		}
		
		return response()->json([
			'title' => 'Invoice',
			'message' => 'Payment was confirmed successfully.',
			'object' => $invoice
		], 201);
		
	}
	
	public function sendToQuickbooks($id)
	{
		
		$invoice = Invoice::find($id);

		if (!$invoice || $invoice->company_id != $this->_getCompany()->id) {
			return response()->json([
				'title' => 'Invoice',
				'message' => 'Record not found',
			], 404);
		}
		
		if (!$this->_hasQuickbooks()) {
			return response()->json([
				'title' => 'Quickbooks',
				'message' => 'No Quickbooks Settings found!',
			], 404);
		}
		
		$result = null;
		
		try {
			
			$quickbooks = new Quickbooks();
		
			$result = $quickbooks->addInvoice($invoice);
			
		} catch (\Exception $e) {
			return response()->json([
				'title' => 'Invoice',
				'message' => 'It was not possible to send the Invoice to Quickbooks',
			], 500);
		}
			
		if ($result) {
			
			$invoice->quickbooks_id = $result->Id;
			$invoice->save();
			
			return response()->json([
				'title' => 'Invoice',
				'message' => 'Invoice was sent to Quickbooks successfully',
			], 201);
			
		} else {
			return response()->json([
				'title' => 'Invoice',
				'message' => 'It was not possible to send the Invoice to Quickbooks',
			], 500);
		}
		
	}
	
	public function checkPaymentsFromQuickbooks()
	{
		
		if (!$this->_hasQuickbooks()) {
			return response()->json([
				'title' => 'Quickbooks',
				'message' => 'No Quickbooks Settings found!',
			], 404);
		}
		
		$invoices = Invoice::where('company_id', $this->_getCompany()->id)
								->whereNotNull('quickbooks_id')
									->where('status', '0')
										->orderBy('date', 'desc')
											->get();
											
		try {
			
			$quickbooks = new Quickbooks();
											
			foreach($invoices as $invoice) {
				
				$qbo_invoice = $quickbooks->getInvoice($invoice->quickbooks_id);
				
				if ($qbo_invoice->Balance == 0) {
					
					$invoice->status = 1;
					$invoice->save();
					
					$customer = Customer::find($invoice->customer_id);
			
					if ($customer) {
						$customer->billed = $customer->billed - $invoice->amount;
						$customer->paid = $customer->paid + $invoice->amount;
						$customer->balance = $customer->balance - $invoice->amount;
						$customer->save();
					}
					
				}
				
			}
			
		} catch (\Exception $e) {
			return response()->json([
				'title' => 'Invoice',
				'message' => 'It was not possible to check Payments from Quickbooks',
			], 500);
		}
										
		return response()->json([
					'title' => 'Invoice',
					'message' => 'Payments were checked successfully.'
				], 200);
		
	}
	
	public function store(Request $request)
    {
		
		if ($request->work_order_id) {
			
			$work_order = WorkOrder::find($request->work_order_id);
			
			if (!$work_order || $work_order->company_id != $this->_getCompany()->id) {
				return response()->json([
					'title' => 'Invoice',
					'message' => 'Work Order not found',
				], 404);
			}
			
			if ($work_order->recurring) {
				return response()->json([
					'title' => 'Invoice',
					'message' => 'Work Order is recurring',
				], 500);
			}
			
			if (count($work_order->invoices) > 0) {
				return response()->json([
					'title' => 'Invoice',
					'message' => 'Work Order already has an invoice',
				], 500);
			}
			
		}
		
		$invoice = $this->_save($request);
		
		if ($invoice) {
			
			if ($invoice->work_order_id) {
				
				$work_order_visits = WorkOrderVisit::where('work_order_id', $invoice->work_order_id)->get();
				
				foreach ($work_order_visits as $work_order_visit) {
					
					$work_order_visit->updated_at = date('Y-m-d H:i:s');
					$work_order_visit->invoice_id = $invoice->id;
					
					$work_order_visit->save();
					
				}
				
			}
			
			if ($this->_hasQuickbooks()) {
				
				$qbo_check = true;
				
				if (!$invoice->customer->quickbooks_id) {
					$qbo_check = false;
				}
				
				foreach ($invoice->description as $item) {
					if (!$item['quickbooks_id']) {
						$qbo_check = false;
						break;
					}
				}
				
				if ($qbo_check) {
					$this->sendToQuickbooks($invoice->id);
				}
				
			}
			
			return response()->json([
				'title' => 'Invoice',
				'message' => 'Invoice was added successfully.',
				'object' => $invoice
			], 201);
			
		} else {
			return response()->json([
				'title' => 'Invoice',
				'message' => 'It was not possible to add the invoice.'
			], 500);
		}
		
    }
	
	private function _save($request) 
    {
		
		$customer = Customer::find($request->customer_id);
		
		if (!$customer || $customer->company_id != $this->_getCompany()->id) {
			return response()->json([
				'title' => 'Invoice',
				'message' => 'Customer not found',
			], 404);
		}
		
		$property = Property::find($request->property_id);
		
		if (!$property || $property->company_id != $this->_getCompany()->id) {
			return response()->json([
				'title' => 'Invoice',
				'message' => 'Property not found',
			], 404);
		}
		
		$created = false;
		
		try {

			$invoice = new Invoice();
				
			$invoice->created_at = date('Y-m-d H:i:s');
			$invoice->updated_at = date('Y-m-d H:i:s');
			$invoice->company_id = $this->_getCompany()->id;
			$invoice->customer_id = $request->customer_id;
			$invoice->property_id = $request->property_id;
			$invoice->work_order_id = (isset($request->work_order_id) && $request->work_order_id) ? $request->work_order_id : null;
			$invoice->date = date('Y-m-d');
			$invoice->date_paid = null;
			
			$arrSendBy = array();
			
			if (isset($customer->preferences['statement_by_email']) && $customer->preferences['statement_by_email'] == true) {
				$arrSendBy[] = 'EMAIL';
			}
			
			if (isset($customer->preferences['statement_by_print']) && $customer->preferences['statement_by_print'] == true) {
				$arrSendBy[] = 'PRINT';
			}
			
			$invoice->send_by = $arrSendBy;
			
			if (isset($customer->preferences['terms'])) {
				$invoice->date_due = date('Y-m-d', strtotime('+' . $customer->preferences['terms'] . ' days', strtotime(date('Y-m-d'))));
			} else {
				$invoice->date_due = date('Y-m-d');
			}
			
			$arrDescription = array();
			
			foreach($request->services as $item) {
				
				$service = Service::find($item['service_id']);
				
				if ($service) {
				
					$arrDescription[] = array(
						'id' => $service->id,
						'quickbooks_id' => $service->quickbooks_id,
						'name' => $service->name,
						'qty' => $item['qty'],
						'price' => $item['price'],
						'type' => 'Service',
						'description' => $service->description
					);
				
				}
				
			}
			
			foreach($request->products as $item) {
				
				$product = Product::find($item['product_id']);
				
				if ($product) {
				
					$arrDescription[] = array(
						'id' => $product->id,
						'quickbooks_id' => $product->quickbooks_id,
						'name' => $product->name,
						'qty' => $item['qty'],
						'price' => $item['price'],
						'type' => 'Product',
						'description' => $product->description
					);
				
				}
				
			}
			
			$invoice->description = $arrDescription;
			$invoice->amount = $request->amount;
			$invoice->discount = $request->discount;
			$invoice->status = 0;

			if ($invoice->save()) {			
				return $invoice;
			}
			
		} catch(\Exception $e) {
			//
		}

        return null;

    }
	
	public function resend(Request $request, $id)
	{
		
		$invoice = Invoice::find($id);
		
		if (!$invoice || $invoice->company_id != $this->_getCompany()->id) {
			return response()->json([
				'title' => 'Invoice',
				'message' => 'Record not found',
			], 404);
		}
		
		if (in_array('EMAIL', $invoice->send_by)) {
				
			if (isset($invoice->customer->contacts['email']) && $invoice->customer->contacts['email']) {
				Mail::to($invoice->customer->contacts['email'])->send(new \App\Mail\InvoiceDetail($invoice, $invoice->customer->account_number));
			}
			
			if (isset($invoice->customer->contacts['email_secondary']) && $invoice->customer->contacts['email_secondary']) {
				Mail::to($invoice->customer->contacts['email_secondary'])->send(new \App\Mail\InvoiceDetail($invoice, $invoice->customer->account_number));
			}
			
		}
		
		return response()->json([
			'title' => 'Invoice',
			'message' => 'Invoice was re-sent successfully.',
			'object' => $invoice
		], 201);
		
	}

}
