<?php

namespace Modules\Ticket\Controllers;

use App\Controllers\BaseController;

use Modules\Ticket\Models\CancelModel;
use Modules\Ticket\Models\TicketModel;
use Modules\Paymethod\Models\PaymethodModel;
use Modules\Trip\Models\PickdropModel;

use Modules\Agent\Models\AgentModel;
use Modules\Agent\Models\Agentcommission;
use Modules\Agent\Models\AgenttotalModel;
use Modules\Ticket\Models\JourneylistModel;
use Modules\Cancellation\Models\CancellationModel;

use App\Libraries\Rolepermission;

class Cancel extends BaseController
{
	protected $Viewpath;
	protected $cancelModel;
	protected $ticketpayModel;
	protected $paymethodModel;
	protected $db;
	protected $agentModel;
    protected $agentCommissionModel;
   

    protected $agetTotalModel;
	
	protected $journeylistModel;
	protected $cancellationModel;
	protected $picdropModel;
	
	public function __construct()
    {

        $this->Viewpath = "Modules\Ticket\Views";
		$this->cancelModel = new CancelModel();
		$this->ticketpayModel = new TicketModel();
		$this->paymethodModel = new PaymethodModel();

		$this->agentModel = new AgentModel();
        $this->agentCommissionModel = new Agentcommission();
		$this->db = \Config\Database::connect();

		$this->agetTotalModel = new AgenttotalModel();

		$this->journeylistModel = new JourneylistModel();
		$this->cancellationModel = new CancellationModel();
		$this->picdropModel = new PickdropModel();
		
    }

	function get_time_difference_in_hours($journeyDate, $journeyTime)
    {
        // Combine journey date and time into one string
        $journeyDateTime = $journeyDate . ' ' . $journeyTime;

        // Convert the journey date and time to a DateTime object (in proper format)
        try {
            $journeyDateTimeObject = new \DateTime($journeyDateTime); // Make sure it handles both date and time
        } catch (Exception $e) {
            return "Invalid date/time format.";
        }

        // Get the current date and time
        $currentDateTime = get_egypt_time('now');

        // If the journey time is later on the same day, we directly calculate the difference
        // Otherwise, we calculate it as the difference across two days
        $interval = $journeyDateTimeObject->diff($currentDateTime);

        // Calculate the total hours difference, including full days converted to hours
        $hoursDifference = $interval->h + ($interval->days * 24);

        // If the journey time is in the future, calculate the total difference in hours including minutes
        if ($interval->invert == 0) {
            // Add minutes as a fraction of an hour
            $hoursDifference += $interval->i / 60; 
        }

        // Add 24 hours for the journey time since it's in the future
        if ($interval->invert == 0) {
            // Round the hours difference to the nearest integer
            $totalHours = ceil($hoursDifference);
            return $totalHours;
        } else {
            // If journey is in the past (if needed, you can handle past scenarios)
            return round($hoursDifference);
        }
    }

	public function new($ticketid,$type)
	{
		if ($type == "ticket" ) {
			
			$data['track_table'] = $this->ticketpayModel
			->select('tickets.*, trips.company_id, schedules.start_time AS journeytimes, journeylists.journeydate') // Adjust columns to select
			->join('trips', 'trips.id = tickets.trip_id', 'left') // Define your LEFT JOIN
			->join("subtrips", "subtrips.trip_id = trips.id", "left")
			->join('schedules', 'schedules.id = trips.schedule_id', 'left') // Define your LEFT JOIN
			->join('journeylists', 'journeylists.booking_id = tickets.booking_id', 'left') // Define your LEFT JOIN
			->where('tickets.id', $ticketid)
			->first();
			if(!empty($data['track_table'])){
	            $pickdrop = $this->picdropModel->select('pickdrops.id as pickdropid,pickdrops.*,stands.*')
                ->join('stands', 'stands.id = pickdrops.stand_id')
                ->where('trip_id', $data['track_table']->subtrip_id)
                ->where('type' , 1)
                ->first();
	            if(empty($pickdrop)){
	                $pickdrop = $this->picdropModel->select('pickdrops.id as pickdropid,pickdrops.*,stands.*')
	                    ->join('stands', 'stands.id = pickdrops.stand_id')
	                    ->where('trip_id', $data['track_table']->trip_id)
	                    ->where('type' , 1)
	                    ->first();
	            }
	         $data['track_table']->journeytime = $pickdrop->time??$data['track_table']->journeytimes;
			}
			$track_table = $data['track_table'];
			//$data['track_table'] = $this->ticketpayModel->find($ticketid);
		}
		$journeyDate = "";
		$journeyTime = "";
		$company_id = 0;
		if(isset($track_table->journeydate)){
			$journeyDate = $track_table->journeydate;
		}
		if(isset($track_table->company_id)){
			$company_id = $track_table->company_id;
		}
		if(isset($track_table->journeytime)){
			$journeyTime = $track_table->journeytime;
		}
		if ($journeyDate != "" && $journeyTime != "") {
		    $journeyDateTime = strtotime($journeyDate . ' ' . $journeyTime);
		    $currentTime = time();

		    if ($journeyDateTime <= $currentTime) {
		        return redirect()->back()->with('fail', 'Journey date/time has already passed.');
		    }
		}

		$diffrentHours = 0;
		if($journeyDate != "" && $journeyTime != ""){
			$diffrentHours = $this->get_time_difference_in_hours($journeyDate, $journeyTime);
		}

		$total_amount = 0;
		if(isset($track_table->paidamount)){
			$total_amount = $track_table->paidamount;
		}
		$cancel_charge = 0;
		$refunded_amount = 0;
		
		if($diffrentHours > 0){
			
			$chargeRecord = $this->cancellationModel->select('*')
                  ->where('hours >=', $diffrentHours)
				  ->where('company_id', $company_id)
                  ->orderBy('hours', 'ASC')
                  ->first();
			
			if(!empty($chargeRecord)){
				$percentage = $chargeRecord->charges;
				if($percentage){
					
					$newAmount = $total_amount * $percentage;
					$cancel_charge = $newAmount / 100;
					if($cancel_charge > 0){
						$refunded_amount = $total_amount - $cancel_charge;
					}else{
						$refunded_amount = $total_amount;
					}
				}
			}else{
				$refunded_amount = $total_amount;
			}
		}
		
		$data['cancel_charge'] = round($cancel_charge);
		$data['refunded_amount'] = round($refunded_amount);
		$data['total_amount'] = round($total_amount);

		


		$data['type'] = $type;
		$data['paymethod'] = $this->paymethodModel->findAll();
		
		$data['module'] =    lang("Localize.ticket_booking") ; 
		$data['title']  =    lang("Localize.cancel_list") ;

		$heading = lang("Localize.ticket").' '.lang("Localize.cancel");
		$data['pageheading'] = $heading;

		echo view($this->Viewpath.'\cancel/new',$data);
	}

	public function create()
	{
        $tableTargetDetail ="";

        $currentuserid = $this->session->get('user_id');
        $type = $this->request->getVar('type');
        $trackTableId = $this->request->getVar('track_table_id');
        $booking_id = $this->request->getVar('booking_id');
        $paymathodid = $this->request->getVar('pay_type_id');
        $paydetail = $this->request->getVar('detail');
        $cancel_fee = $this->request->getVar('cancel_fee');


        $validCancel = array(
            "booking_id" => $booking_id,
            "type" => $type,
            "cancel_by" => $currentuserid,
            
          );
         
        $cancel = array(
            "booking_id" => $booking_id,
            "cancel_fee" => $cancel_fee,
            "track_table_id" => $trackTableId,
            "type" => $type,
            "detail" => $paydetail,
            "pay_type_id" => $paymathodid,
            "cancel_by" => $currentuserid,
         );

		 if ($this->validation->run($validCancel, 'cancel')) {


			$this->db->transStart();
			
			$this->cancelModel->insert($cancel);

			if ($type == "ticket") {

				$data = [
					'id' => $trackTableId,
					'cancel_status' => 1,
				];
				
				$this->ticketpayModel->save($data);

				$tableTargetDetail = $this->ticketpayModel->where('booking_id',$booking_id)->first();
				
			}
			
			else {
				// $tableTargetDetail = ""
			}


			$userRole = $this->session->get('role_id');

			if ($userRole == 2) {

				if (!empty($cancel_fee)) {
					
					$userid = $tableTargetDetail->passanger_id;
					$subtripid = $tableTargetDetail->subtrip_id;
					$payDetail = $paydetail;
					$incometype = "income";
					$detail = "Cancel fee (".$booking_id.") ";
					$amount = $cancel_fee;

					agentIncomeCommission($currentuserid,$amount,$booking_id,$subtripid,$userid,$detail);
					
					agentTotal($currentuserid,$amount,$booking_id,$incometype,$payDetail);
				
					}

			   

			  }



			if (!empty($cancel_fee)) {
				
				$intype = "income";
                $detail = "Cancel (".$booking_id.") ";
				$amount = $cancel_fee;
                accoutTranjection($intype, $detail, $amount, $currentuserid, $booking_id, "booking");

				paymethodTeanjection($booking_id,$paymathodid,$cancel_fee,$paydetail,$tableTargetDetail->trip_id,$tableTargetDetail->subtrip_id,$currentuserid);
			
				}

				$this->journeylistModel->where('booking_id', $booking_id)->delete();

			$this->db->transComplete();

			return redirect()->route('ticketindex-cancel')->with("success", "Refund Successful");
			 
		 } 
		 else
		  {
			if ($type == "ticket" ) {
				$data['track_table'] = $this->ticketpayModel->find($trackTableId);
			}

			$data['type'] = $type;
			$data['paymethod'] = $this->paymethodModel->findAll();
			$data['validation'] = $this->validation;
			
			$data['module'] =    lang("Localize.ticket_booking") ; 
			$data['title']  =    lang("Localize.cancel_list") ;

			echo view($this->Viewpath.'\cancel/new',$data);
		  }
		 
    }


	public function indexTicket()
	{
		$roleId     = session()->get("role_id");
		$companyId  = session()->get("company_id");
		if($roleId == 1){
			$data['cancel'] = $this->cancelModel->where('type',"ticket")->orderBy('id', 'DESC')->withDeleted()->findAll();
		}else{
			$userRole = $this->session->get('role_id');
        	$userId = $this->session->get('user_id');
			$this->cancelModel
				->select('cancels.*')
				->join('tickets', 'tickets.id = cancels.track_table_id', 'left')
		        ->join('trips', 'trips.id = tickets.trip_id', 'left')
	            // ->where('trips.company_id', $companyId)
				->where('type',"ticket");
        	if (!in_array($userRole,[1,2,7])) {
        		$rolepermissionLibrary = new Rolepermission();
	            if (!$rolepermissionLibrary->create('all_tickets')) {
	                $this->cancelModel->where('cancel_by', $userId);
	            }else{
	                $this->cancelModel->where('trips.company_id', $companyId);
	            }
	        	
        	}else{
	            if(in_array($userRole,[7])){
	            	$this->cancelModel->where('trips.company_id', $companyId);	
	            }if(in_array($userRole,[2])){
					$this->cancelModel->whereIn('trips.company_id', explode(",", session()->get('company_id')))->where('cancel_by', $userId);
	            }
	        }
			$data['cancel'] = 	$this->cancelModel->orderBy('id', 'DESC')->withDeleted()->findAll();
		}
		
		$data['module'] =    lang("Localize.ticket_booking") ; 
		$data['title']  =    lang("Localize.cancel_list") ;
		$heading = lang("Localize.ticket").' '.lang("Localize.cancel_list");
		$data['pageheading'] = $heading;
		
		echo view($this->Viewpath.'\cancel\index',$data);
	}
		public function serverListCancel()
	{
		$request = service('request');

		// Role and company ID from session
		$roleId = session()->get('role_id');
		$companyId = session()->get('company_id');
		$userId = session()->get('user_id');
		$rolepermissionLibrary = new Rolepermission();

		// DataTables request values
		$draw   = $request->getPost('draw');
		$start  = $request->getPost('start');
		$length = $request->getPost('length');
		$searchValue = $request->getPost('search')['value'] ?? '';

		// Column map
		$columns = [
			0 => null, // index
			1 => 'cancels.booking_id', // booking_id
			2 => 'cancels.cancel_fee', // amount
			3 => 'cancels.type', // type
			4 => 'cancels.detail', // payment details
			5 => 'cancels.created_at' // date
		];

		// Order column & direction
		$order = $request->getPost('order');
		$orderColumnIndex = !empty($order) && isset($order[0]['column']) ? $order[0]['column'] : 5;
		$orderDirection   = !empty($order) && isset($order[0]['dir']) ? $order[0]['dir'] : 'desc';

		// ---- TOTAL RECORDS ----
		$countBuilder = $this->db->table('cancels');
		$countBuilder->select('cancels.id')
			->where('cancels.type', 'ticket');

		// Apply role-based filtering for total count
		if ($roleId == 1) {
			// Super admin sees all
		} else {
			$countBuilder->join('tickets', 'tickets.id = cancels.track_table_id', 'left')
				->join('trips', 'trips.id = tickets.trip_id', 'left');

			if (!in_array($roleId, [1, 2, 7])) {
				if (!$rolepermissionLibrary->create('all_tickets')) {
					$countBuilder->where('cancels.cancel_by', $userId);
				} else {
					$countBuilder->where('trips.company_id', $companyId);
				}
			} else {
				if (in_array($roleId, [7])) {
					$countBuilder->where('trips.company_id', $companyId);
				}
				if (in_array($roleId, [2])) {
					$countBuilder->whereIn('trips.company_id', explode(",", $companyId))
						->where('cancels.cancel_by', $userId);
				}
			}
		}

		$totalRecords = $countBuilder->countAllResults(false);

		// ---- FILTERED QUERY ----
		$builder = $this->db->table('cancels');
		$builder->select('cancels.id, cancels.booking_id, cancels.cancel_fee, cancels.type, cancels.detail, cancels.created_at')
			->where('cancels.type', 'ticket');

		// Apply role-based filtering
		if ($roleId == 1) {
			// Super admin sees all
		} else {
			$builder->join('tickets', 'tickets.id = cancels.track_table_id', 'left')
				->join('trips', 'trips.id = tickets.trip_id', 'left');

			if (!in_array($roleId, [1, 2, 7])) {
				if (!$rolepermissionLibrary->create('all_tickets')) {
					$builder->where('cancels.cancel_by', $userId);
				} else {
					$builder->where('trips.company_id', $companyId);
				}
			} else {
				if (in_array($roleId, [7])) {
					$builder->where('trips.company_id', $companyId);
				}
				if (in_array($roleId, [2])) {
					$builder->whereIn('trips.company_id', explode(",", $companyId))
						->where('cancels.cancel_by', $userId);
				}
			}
		}

		// Global search
		if (!empty($searchValue)) {
			$builder->groupStart()
				->like('cancels.booking_id', $searchValue)
				->orLike('cancels.cancel_fee', $searchValue)
				->orLike('cancels.type', $searchValue)
				->orLike('cancels.detail', $searchValue)
				->orLike('cancels.created_at', $searchValue)
				->groupEnd();
		}

		// Create a separate builder for filtered count
		$filteredCountBuilder = $this->db->table('cancels');
		$filteredCountBuilder->select('cancels.id')
			->where('cancels.type', 'ticket');

		// Apply role-based filtering for filtered count
		if ($roleId == 1) {
			// Super admin sees all
		} else {
			$filteredCountBuilder->join('tickets', 'tickets.id = cancels.track_table_id', 'left')
				->join('trips', 'trips.id = tickets.trip_id', 'left');

			if (!in_array($roleId, [1, 2, 7])) {
				if (!$rolepermissionLibrary->create('all_tickets')) {
					$filteredCountBuilder->where('cancels.cancel_by', $userId);
				} else {
					$filteredCountBuilder->where('trips.company_id', $companyId);
				}
			} else {
				if (in_array($roleId, [7])) {
					$filteredCountBuilder->where('trips.company_id', $companyId);
				}
				if (in_array($roleId, [2])) {
					$filteredCountBuilder->whereIn('trips.company_id', explode(",", $companyId))
						->where('cancels.cancel_by', $userId);
				}
			}
		}

		// Apply search filter for filtered count
		if (!empty($searchValue)) {
			$filteredCountBuilder->groupStart()
				->like('cancels.booking_id', $searchValue)
				->orLike('cancels.cancel_fee', $searchValue)
				->orLike('cancels.type', $searchValue)
				->orLike('cancels.detail', $searchValue)
				->orLike('cancels.created_at', $searchValue)
				->groupEnd();
		}

		// ---- TOTAL FILTERED ----
		$totalRecordwithFilter = $filteredCountBuilder->countAllResults(false);

		// ---- ORDERING ----
		if (isset($columns[$orderColumnIndex]) && $columns[$orderColumnIndex] !== null) {
			$builder->orderBy($columns[$orderColumnIndex], $orderDirection);
		} else {
			$builder->orderBy('cancels.id', 'desc');
		}

		// ---- PAGINATION ----
		if ($length > 0) {
			$builder->limit($length, $start);
		}

		// ---- FETCH RECORDS ----
		$records = $builder->get()->getResult();

		// ---- FORMAT JSON ----
		$data = [];
		$i = $start + 1;

		foreach ($records as $row) {
			$data[] = [
				"index" => $i++,
				"booking_id" => esc($row->booking_id ?? ''),
				"cancel_fee" => esc($row->cancel_fee ?? ''),
				"type" => esc($row->type ?? ''),
				"detail" => esc($row->detail ?? ''),
				"created_at" => esc($row->created_at ?? '')
			];
		}

		return $this->response->setJSON([
			"draw" => intval($draw),
			"recordsTotal" => $totalRecords,
			"recordsFiltered" => $totalRecordwithFilter,
			"data" => $data
		]);
	}
}
