<?php

namespace App\Livewire;

use Livewire\Component;
use App\Models\User;
use App\Models\Category;
use App\Models\RevenueStream;
use App\Models\Zone;
use App\Models\FinanceBill;
use App\Models\FinanceBillDetails;
use App\Models\FinanceBillApprovals;
use App\Models\Amendment;
use Carbon\Carbon;
use App\Models\FinanceBill as FinanceBillModel;
use App\Models\FinanceBillDetails as FinanceBillDetailsModel;
use Livewire\Attributes\On;
use Stevebauman\Purify\Facades\Purify;
use Illuminate\Support\Facades\Mail;
use App\Mail\FinanceBillDraftedEmail;
use  App\Events\FinanceBillDrafted;
use App\Jobs\ProcessFinanceBillDraftedEmails;
use DB;

class Financebills extends Component
{
	protected $listeners=['openAddModal','setPeriodStart','setPeriodEnd','editFinanceBill','openFinanceBill','openAmendmentModal','retract','viewFinanceBill'];
	
	// add the properties for input fields
	public $Identifier;
	public $FinanceBillID;
    public $PeriodStart;
	public $PeriodEnd;
	public $BillDetailID;
	public $StreamID;
	public $StreamName;
	public $ZoneID;
	public $ZoneName;
	public $Name;
	public $Amount;
	public $Draft;
	public $UserID;
	public $revenuestreams;
	public $zones;
	public $DrafterID;
	public $DraftedOn;
	public $canUpdate;
	public $Amendment;
	public $draft_id;
	public $DraftID;
	public $LoggedInUser;
	public $has_responded;
	public $Response;
	public $has_been_actioned;
	
	protected $rules = [
		'PeriodStart' => 'required',
		'PeriodEnd' => 'required',
		'StreamID' => 'required',
		'ZoneID' => 'required',
		'Name' => 'required',
		'Amount' => 'required|numeric',
    ];
	
	protected $messages = [
        'PeriodStart.required' => 'Start period is required',
		'PeriodEnd.required' => 'End period is required',
		'StreamID.required' => 'Revenue stream is required',
		'ZoneID.required' => 'Zone is required',
		'Name.required' => 'Finance Bill name is required',
		'Amount.required' => 'Amount is required',
		'Amount.numeric' => 'Amount must be numeric. No comma(s) (,) allowed'
    ];
	
    public function render()
    {
		$this->revenuestreams= RevenueStream::orderBy('StreamName','asc')->get();
		$this->zones= Zone::orderBy('ZoneName','asc')->get();
        return view('livewire.financebills');
    }
	
	public function updated($Amount)
    {
        $this->validateOnly($Amount);
    }
	
	//view financebill
    public function viewFinanceBill($id)
    {
		$financebill = FinanceBillModel::find($id);
		
		if($financebill){
			$this->FinanceBillID = $financebill->FinanceBillID;
			$this->Identifier=$financebill->Identifier;
			$this->PeriodStart=Carbon::parse($financebill->PeriodStart)->format('d/m/Y');
			$this->PeriodEnd = Carbon::parse($financebill->PeriodEnd)->format('d/m/Y');
			$this->StreamID=$financebill->financebilldetails->StreamID;
			$this->StreamName=$financebill->financebilldetails->stream_name;
			$this->ZoneID=$financebill->financebilldetails->ZoneID;
			$this->ZoneName=$financebill->financebilldetails->zone_name;
			$this->Name=$financebill->financebilldetails->Name;
			$this->Amount=number_format($financebill->financebilldetails->Amount,2);
			$this->Draft=$financebill->financebilldetails->Draft;
			$this->DraftedOn=Carbon::parse($financebill->CreatedAt)->format('d/m/Y h:i A');
			$this->DraftID=$financebill->financebilldetails->DraftID;
			$this->LoggedInUser=auth()->user()->id;
			$this->DrafterID=User::where('id',$financebill->UserID)->pluck('name')->first();
			
			$DrafterID=$financebill->financebilldetails->UserID;
			$LoggedinID=auth()->user()->id;
			$canUpdate=0;
			if($LoggedinID==$DrafterID){
				$canUpdate=1;
			}
			$this->canUpdate=$canUpdate;
			
			$has_responded=0;
				$response=FinanceBillApprovals::where('FinanceBillID',$financebill->FinanceBillID)
										->where('UserID',auth()->user()->id)
										->first();
				
				$voted=0;
				if($response){
					$has_responded=1;
					$voted=$response->Response;
				}
				$this->has_responded=$has_responded;
				$this->Response=$voted;
				
				$has_been_actioned=0;
				$passed=FinanceBillDetailsModel::where('FinanceBillID',$financebill->FinanceBillID)
										->pluck('Status')
										->first();
				if($passed !=0){
					$has_been_actioned=1;
				}
				$this->has_been_actioned=$has_been_actioned;
			
			$this->dispatch('openModal', 'viewModal');
		}
		else{
            return redirect()->back();
        }
		
    }
	
	//open financebill
    public function openFinanceBill($id)
    {
		$financebill = FinanceBillDetailsModel::find($id);
		//dd($financebill->financebilldetails->Amount);
		
		if($financebill){
			$this->FinanceBillID = $financebill->FinanceBillID;
			$this->Identifier=$financebill->financebill->Identifier;
			$this->PeriodStart=$financebill->financebill->PeriodStart;
			$this->PeriodEnd = $financebill->financebill->PeriodEnd;
			$this->StreamID=$financebill->StreamID;
			$this->ZoneID=$financebill->ZoneID;
			$this->Name=$financebill->Name;
			$this->Amount=$financebill->Amount;
			$this->Draft=$financebill->Draft;
			$this->DraftID=$financebill->DraftID;
			$this->LoggedInUser=auth()->user()->id;
			$this->DrafterID=User::where('id',$financebill->financebill->UserID)->pluck('name')->first();
			
			$DrafterID=$financebill->financebill->UserID;
			$LoggedinID=auth()->user()->id;
			$canUpdate=0;
			if($LoggedinID==$DrafterID){
				$canUpdate=1;
			}
			$this->canUpdate=$canUpdate;
			
			$has_responded=0;
				$response=FinanceBillApprovals::where('FinanceBillID',$financebill->FinanceBillID)
										->where('DraftID',$financebill->DraftID)
										->where('UserID',auth()->user()->id)
										->first();
				
				$voted=0;
				if($response){
					$has_responded=1;
					$voted=$response->Response;
				}
				$this->has_responded=$has_responded;
				$this->Response=$voted;
			
			$draft_id=0;
			$drafted=FinanceBillDetailsModel::where('FinanceBillID',$this->FinanceBillID)->whereNotNull('Draft')->first();
				if($drafted){
					$last_draft_id = FinanceBillDetailsModel::where('FinanceBillID',$this->FinanceBillID)->count();
					$draft_id=$last_draft_id+1;
				}
			$this->draft_id=$draft_id;
			
			$this->dispatch('openModal', 'openModal');
			$this->dispatch('DraftContent', content:$financebill->Draft);
		}
		else{
            return redirect()->back();
        }
		
    }
	
	//open amendement modal
    public function openAmendmentModal($id)
    {
		$financebill = FinanceBillDetailsModel::find($id);
		
		if($financebill){
			$this->FinanceBillID = $financebill->FinanceBillID;
			$this->PeriodStart=$financebill->financebill->PeriodStart;
			$this->PeriodEnd = $financebill->financebill->PeriodEnd;
			$this->StreamID=$financebill->StreamID;
			$this->Identifier=$financebill->financebill->Identifier;
			$this->DraftID=$financebill->DraftID;
			$this->DrafterID=User::where('id',$financebill->financebill->UserID)->pluck('name')->first();
			
			$this->dispatch('openModal', 'amendmentModal');
		}
		else{
            return redirect()->back();
        }
		
    }
	
	// save amendment
    public function saveAmendmentDraft()
    {
        // validate the data
        $this->validate([
            'FinanceBillID' => 'required',
			'Amendment' => 'required'
        ]);
		
		$exists=Amendment::where('FinanceBillID', $this->FinanceBillID)
								->where('Amendment', $this->Amendment)
								->first();
		
		if($exists){
			//toast
			$this->dispatch('alert', [
				'type' => 'error',
				'message' => "Suggested Amendment Already Exists!",
			]);
			return;
		}

		$cleanedAmendment = Purify::clean($this->Amendment);
		$amendment=Amendment::create([
            'FinanceBillID' => $this->FinanceBillID,
			'Amendment' => $cleanedAmendment,
			'UserID' => auth()->user()->id,
        ]);
		
		$this->resetFields();
		
		//event
        $this->dispatch('closeModal', 'amendmentModal');
		$this->dispatch('refreshDatatable');
		
		//toast
        $this->dispatch('alert', [
            'type' => 'success',
            'message' => "Suggested Amendment Added Successfully!",
        ]);
    }
	
	// add new finance bill
    public function saveFinanceBill()
    {
        // validate the data
        $this->validate();
		
		$exists=DB::table('financebills')
					->join('financebilldetails','financebills.FinanceBillID','=','financebilldetails.FinanceBillID')
					->where('PeriodStart', $this->PeriodStart)
					->where('PeriodEnd', $this->PeriodEnd)
					->where('Name', $this->Name)
					->first();
		
		if($exists){
			//toast
			$this->dispatch('alert', [
				'type' => 'error',
				'message' => "Finance Bill Already Exists!",
			]);
			return;
		}
		$last_id = FinanceBill::latest('FinanceBillID')->first();
		if($last_id){
			$next_id=$last_id->FinanceBillID+1;
		}
		else{
			$next_id=1;
		}
		
		$identifier='FB'.sprintf('%08d', $next_id);

		$financebill=FinanceBillModel::create([
			'Identifier' => $identifier,
            'PeriodStart' => $this->PeriodStart,
			'PeriodEnd' => $this->PeriodEnd,
			'UserID' => auth()->user()->id,
        ]);
		
		$lastId = $financebill->FinanceBillID;
		
		$financebilldetails=FinanceBillDetailsModel::create([
            'FinanceBillID' => $lastId,
			'StreamID' => $this->StreamID,
			'ZoneID' => $this->ZoneID,
			'Name' => $this->Name,
			'Amount' => $this->Amount,
        ]);
		
		$mailData = [
					'Name' => $this->Name,
					'UserID' => auth()->user()->name,
					'PeriodStart' => Carbon::parse($this->PeriodStart)->format('d/m/Y'),
					'PeriodEnd' => Carbon::parse($this->PeriodEnd)->format('d/m/Y'),
					'StreamID' => RevenueStream::where('StreamID',$this->StreamID)->pluck('StreamName')->first(),
					'ZoneID' => Zone::where('ZoneID',$this->ZoneID)->pluck('ZoneName')->first(),
					'Amount' => $this->Amount,
					'CreatedAt' => date('d/m/Y h:i A'),
					'Url' => config('app.url').'/public/admin/financebills',
					];
					
		//email alert to everyone			
		dispatch(new ProcessFinanceBillDraftedEmails($mailData));
					
		//email alert to everyone
		/*$emails=DB::table('users')->pluck('email')->toArray();	
		
		foreach ($emails as $recipient) {			
			Mail::to($recipient)->send(new FinanceBillDraftedEmail($mailData));
		}*/
		// Trigger the event
		//event(new FinanceBillDrafted($financebill));
		
		$this->resetFields();
		
		//event
        $this->dispatch('closeModal', 'addModal');
		$this->dispatch('refreshDatatable');
		
		//toast
        $this->dispatch('alert', [
            'type' => 'success',
            'message' => "Finance Bill Added Successfully!",
        ]);
    }
	
	//edit financebill
    public function editFinanceBill($id)
    {
		$financebill = FinanceBillModel::find($id);
		
		if($financebill){
			$this->FinanceBillID = $financebill->FinanceBillID;
			$this->PeriodStart=$financebill->PeriodStart;
			$this->PeriodEnd = $financebill->PeriodEnd;
			$this->StreamID=$financebill->financebilldetails->StreamID;
			$this->ZoneID=$financebill->financebilldetails->ZoneID;
			$this->Name=$financebill->financebilldetails->Name;
			$this->Amount=$financebill->financebilldetails->Amount;
			$this->Draft=$financebill->financebilldetails->Draft;
			
			$this->dispatch('openModal', 'editModal');
		}
		else{
            return redirect()->back();
        }
		
    }
	
	public function updateFinanceBill()
    {
        $this->validate();

		$financebill = FinanceBillModel::find($this->FinanceBillID);
		$financebill->PeriodStart=$this->PeriodStart;
		$financebill->PeriodEnd=$this->PeriodEnd;
		$financebill->save();
		
		$financebilldetails = FinanceBillDetailsModel::where('FinanceBillID',$this->FinanceBillID)->first();
		$financebilldetails->StreamID=$this->StreamID;
		$financebilldetails->ZoneID=$this->ZoneID;
		$financebilldetails->Name=$this->Name;
		$financebilldetails->Amount=$this->Amount;
		$financebilldetails->save();
		
        $this->resetFields();
		
		//event
        $this->dispatch('closeModal', 'editModal');
		$this->dispatch('refreshDatatable');
		
		//toast
        $this->dispatch('alert', [
            'type' => 'success',
            'message' => "Finance Bill Updated Successfully!",
        ]);
 

    }
	
	public function resetFields()
    {
        $this->resetValidation();
        $this->PeriodStart = '';
		$this->PeriodEnd = '';
		$this->StreamID = '';
		$this->ZoneID = '';
		$this->Amount = '';
		$this->Name = '';
		$this->Description = '';
    }
	
	public function openAddModal()
    {
        $this->resetValidation();
        $this->PeriodStart = '';
		$this->PeriodEnd = '';
		$this->StreamID = '';
		$this->ZoneID = '';
		$this->Name = '';
		$this->Amount = '';
		$this->Name = '';
		$this->Description = '';
		$this->dispatch('openModal', 'addModal');
    }
	
	#[On('financebill-deleted')]
    public function deleteFinanceBill($id)
    {
		$deletefbdetails=FinanceBillDetailsModel::where('FinanceBillID',$id)->delete(); //child delete first
		$deletefb=FinanceBillModel::find($id)->delete();
		
		$this->dispatch('refreshDatatable');
		//toast
		$this->dispatch('alert', [
			'type' => 'success',
			'message' => "Finance BIll  Deleted Successfully!",
		]);

    }
	
	public function setPeriodStart($startDate)
    {
		$this->PeriodStart=$startDate;
	}
	
	public function setPeriodEnd($endDate)
    {
		$this->PeriodEnd=$endDate;
	}
	
	#[On('approveBill')] 
		public function approve($FinanceBillID,$LoggedInUser)
		{
			$financebill = new FinanceBillApprovals();
			$financebill->FinanceBillID = $FinanceBillID;
			$financebill->Response = 1;
			$financebill->UserID = $LoggedInUser;
			$financebill->save();
			
			$this->dispatch('refreshDatatable');
			//$this->dispatch('refreshComponent');
			$this->dispatch('closeModal', 'openModal');
			
			//toast
			$this->dispatch('alert', [
				'type' => 'success',
				'message' => "Your approval was logged successfully!",
			]);
		}
	
		#[On('rejectBill')] 
		public function reject($FinanceBillID,$LoggedInUser)
		{
			$financebill = new FinanceBillApprovals();
			$financebill->FinanceBillID = $FinanceBillID;
			$financebill->Response = 2;
			$financebill->UserID = $LoggedInUser;
			$financebill->save();
			
			$this->dispatch('refreshDatatable');
			//$this->dispatch('refreshComponent');
			$this->dispatch('closeModal', 'viewModal');
			
			//toast
			$this->dispatch('alert', [
				'type' => 'success',
				'message' => "Your rejection was logged successfully!",
			]);
		}
		
		#[On('retractDecision')] 
		public function retract($FinanceBillID,$LoggedInUser)
		{
			$approval = FinanceBillApprovals::where('FinanceBillID',$FinanceBillID)->where('UserID',$LoggedInUser)->first();
			
			if($approval){
			$approval->delete();
			$this->dispatch('refreshDatatable');
			//$this->dispatch('refreshComponent');
			$this->dispatch('closeModal', 'viewModal');
			
			//toast
			$this->dispatch('alert', [
				'type' => 'success',
				'message' => "Your decision was retracted successfully!",
			]);
			}
			else{
				$this->dispatch('alert', [
				'type' => 'error',
				'message' => "No decision for this finance bill was found!",
			]);
			}
		}
		
		#[On('passBill')] 
		public function pass($FinanceBillID,$LoggedInUser)
		{
			FinanceBillDetailsModel::where('FinanceBillID',$FinanceBillID)->update(['Status'=>1]);
			
			$this->dispatch('refreshDatatable');
			//$this->dispatch('refreshComponent');
			$this->dispatch('closeModal', 'viewModal');
			
			//toast
			$this->dispatch('alert', [
				'type' => 'success',
				'message' => "Finance bill was passed successfully!",
			]);
		}
	
		#[On('annulBill')] 
		public function annul($FinanceBillID,$LoggedInUser)
		{
			FinanceBillDetailsModel::where('FinanceBillID',$FinanceBillID)->update(['Status'=>2]);
			
			$this->dispatch('refreshDatatable');
			//$this->dispatch('refreshComponent');
			$this->dispatch('closeModal', 'viewModal');
			
			//toast
			$this->dispatch('alert', [
				'type' => 'success',
				'message' => "Finance bill was annuled successfully!",
			]);
		}
	
}
