<?php

namespace Modules\Ticket\Controllers;

use App\Controllers\BaseController;

use Modules\Ticket\Models\PartialpaidModel;
use Modules\Ticket\Models\TicketModel;
use Modules\Paymethod\Models\PaymethodModel;
use Modules\Ticket\Models\RefundModel;
use Modules\Agent\Models\AgentModel;
use Modules\Agent\Models\Agentcommission;
use Modules\Agent\Models\AgenttotalModel;
use Modules\Ticket\Models\JourneylistModel;

class Refund extends BaseController
{
	protected $Viewpath;
	protected $partialpayModel;
	protected $ticketpayModel;
	protected $paymethodModel;
	protected $db;
	protected $agentModel;
    protected $agentCommissionModel;
    protected $refundModel;

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

        $this->Viewpath = "Modules\Ticket\Views";
		$this->partialpayModel = new PartialpaidModel();
		$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->refundModel = new RefundModel();

		$this->journeylistModel = new JourneylistModel();
    }

	public function new($ticketid,$type)
	{
		if ($type == "ticket" ) {
			$data['track_table'] = $this->ticketpayModel->find($ticketid);
		}
		

		$data['type'] = $type;
		$data['paymethod'] = $this->paymethodModel->findAll();

		$data['module'] =    lang("Localize.ticket_booking") ; 
		$data['title']  =    lang("Localize.refund_list") ;

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

		echo view($this->Viewpath.'\refund/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_method');
		$paydetail = $this->request->getVar('detail');
		$refun_fee = $this->request->getVar('refund_fee');


		$validRefund = array(
			"booking_id" => $booking_id,
			"type" => $type,
			"refund_by" => $currentuserid,
			
		  );
		 
		$refund = array(
			"booking_id" => $booking_id,
			"refund_fee" => $refun_fee,
			"track_table_id" => $trackTableId,
			"type" => $type,
			"detail" => $paydetail,
			"pay_type_id" => $paymathodid,
			"refund_by" => $currentuserid,
		 );





		 if ($this->validation->run($validRefund, 'refund')) {

			$this->db->transStart();
			
			$this->refundModel->insert($refund);

			if ($type == "ticket") {

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

				$tableTargetDetail = $this->ticketpayModel->where('booking_id',$booking_id)->first();

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

			$totalamount = $this->partialpayModel->selectSum('paidamount')->where('booking_id',$booking_id)->findAll();

			$refundAmount = (int)$totalamount[0]->paidamount;
			
		

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

			if ($userRole == 2) {

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

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

			   

			  }

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

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

			  	$paymethod_id = $paymathodid;
                $payDetail = $paydetail;
                $extype = "expense";
                $detail = "Refund (".$booking_id.") ";
                accoutTranjection($extype, $detail, $refundAmount, $currentuserid, $booking_id, "booking");


				$agetCommission = $this->agentCommissionModel->where('booking_id',$booking_id)->findAll();

				foreach ($agetCommission as $key => $commissionValue) {

					$data = [
						'id' => $commissionValue->id,
						'commission' => "refund",
					];
					
					$this->agentCommissionModel->save($data);
					
				}
			
				$agetTotal = $this->agetTotalModel->where('booking_id',$booking_id)->where('expense',0)->findAll();

				foreach ($agetTotal as $key => $totalvalue) {
					
					$data = [
						'agent_id' => $totalvalue->agent_id,
						'booking_id' => $totalvalue->booking_id,
						'income' => 0,
						'expense' => $totalvalue->income,
						'detail' => "Refund",
					];

					$this->agetTotalModel->insert($data);
				}

			

				$this->db->transComplete();
			
			return redirect()->route('ticketindex-refund')->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.refund_list") ;

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

		}
	}

	public function indexTicket()
	{
		$data['module'] =    lang("Localize.ticket_booking") ; 
		$data['title']  =    lang("Localize.refund_list") ;

		$roleId     = session()->get("role_id");
		$companyId  = session()->get("company_id");
		if ($roleId == 1) {
			$data['refund'] = $this->refundModel
				->select('refunds.*')
				->join('tickets', 'tickets.id = refunds.track_table_id', 'inner')
				->where('refunds.type', 'ticket')
				->groupStart()
					->where('tickets.bookby_user_type !=', 'passanger')
					->orWhere('tickets.bookby_user_type', null)
				->groupEnd()
				->orderBy('refunds.id', 'DESC')
				->withDeleted()
				->findAll();
		} else {
			$data['refund'] = $this->refundModel
				->select('refunds.*')
				->join('tickets', 'tickets.id = refunds.track_table_id', 'inner')
				->join('trips', 'trips.id = tickets.trip_id', 'left')
				->where('trips.company_id', $companyId)
				->where('refunds.type', 'ticket')
				->groupStart()
					->where('tickets.bookby_user_type !=', 'passanger')
					->orWhere('tickets.bookby_user_type', null)
				->groupEnd()
				->orderBy('refunds.id', 'DESC')
				->withDeleted()
				->findAll();
		}

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

		echo view($this->Viewpath.'\refund/index',$data);
	}
	public function serverListRefund()
	{
		$request = service('request');

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

		// 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 => 'refunds.booking_id', // booking_id
			2 => 'refunds.refund_fee', // amount
			3 => 'refunds.type', // type
			4 => 'refunds.detail', // payment details
			5 => 'refunds.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('refunds');
		$countBuilder->select('refunds.id')
			->where('refunds.type', 'ticket')
			->join('tickets', 'tickets.id = refunds.track_table_id', 'inner')
			->groupStart()
				->where('tickets.bookby_user_type !=', 'passanger')
				->orWhere('tickets.bookby_user_type', null)
			->groupEnd();

		if ($roleId != 1) {
			$countBuilder->join('trips', 'trips.id = tickets.trip_id', 'left')
				->where('trips.company_id', $companyId);
		}

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

		// ---- FILTERED QUERY ----
		$builder = $this->db->table('refunds');
		$builder->select('refunds.id, refunds.booking_id, refunds.refund_fee, refunds.type, refunds.detail, refunds.created_at')
			->where('refunds.type', 'ticket')
			->join('tickets', 'tickets.id = refunds.track_table_id', 'inner')
			->groupStart()
				->where('tickets.bookby_user_type !=', 'passanger')
				->orWhere('tickets.bookby_user_type', null)
			->groupEnd();

		if ($roleId != 1) {
			$builder->join('trips', 'trips.id = tickets.trip_id', 'left')
				->where('trips.company_id', $companyId);
		}

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

		$filteredCountBuilder = $this->db->table('refunds');
		$filteredCountBuilder->select('refunds.id')
			->where('refunds.type', 'ticket')
			->join('tickets', 'tickets.id = refunds.track_table_id', 'inner')
			->groupStart()
				->where('tickets.bookby_user_type !=', 'passanger')
				->orWhere('tickets.bookby_user_type', null)
			->groupEnd();

		if ($roleId != 1) {
			$filteredCountBuilder->join('trips', 'trips.id = tickets.trip_id', 'left')
				->where('trips.company_id', $companyId);
		}

		// Apply search filter for filtered count
		if (!empty($searchValue)) {
			$filteredCountBuilder->groupStart()
				->like('refunds.booking_id', $searchValue)
				->orLike('refunds.refund_fee', $searchValue)
				->orLike('refunds.type', $searchValue)
				->orLike('refunds.detail', $searchValue)
				->orLike('refunds.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('refunds.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 ?? ''),
				"refund_fee" => esc($row->refund_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
		]);
	}
}
