<?php

namespace Modules\Coupon\Controllers;

use App\Controllers\BaseController;
use Modules\Coupon\Models\CouponModel;
use Modules\Trip\Models\SubtripModel;
use Modules\Location\Models\LocationModel;
use App\Libraries\Rolepermission;
use Modules\Company\Models\CompanyModel;
use Modules\Trip\Models\TripModel;
use Modules\Coupon\Models\CouponDetailsModel;


class Coupon extends BaseController
{
    protected $Viewpath;
    protected $couponModel;
    protected $tripModel;
    protected $subtripModel;
    protected $locationModel;
    protected $companyModel;
    protected $couponDetailsModel;
    protected $db;

    public function __construct()
    {
        $this->Viewpath = "Modules\Coupon\Views";
        $this->couponModel = new CouponModel();
        $this->tripModel = new TripModel();
        $this->subtripModel = new SubtripModel();
        $this->locationModel = new LocationModel();
        $this->companyModel = new CompanyModel();
        $this->couponDetailsModel = new CouponDetailsModel();
        $this->db = \Config\Database::connect();
    }

    public function new()
    {
        
        // $data['tripGroups'] = $this->subtripModel
        //     ->select('subtrips.id')
        //     ->withLocations()
        //     ->active()
        //     ->getGroup();
        
        $companyId = session()->get('company_id'); 
        $data['module'] =    lang("Localize.coupon");
        $data['title']  =    lang("Localize.add_coupon");
        $data['pageheading'] = lang("Localize.add_coupon");
        $data['roleId'] = session()->get('role_id');
        $data['companies'] = $this->companyModel->findAll();

        $data['companyId'] = $companyId;
        $data['tripGroups'] = $this->subtripModel->getTripsByCompany([$companyId]);

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

    public function create()
    {
        // $data = $this->request->getVar();
        // var_dump($data);
        // exit;
        $subtrip = $this->subtripModel->where('status', 1)->findAll();
        $locationname = $this->locationModel->findAll();

        foreach ($subtrip as $skey => $subtripvalue) {
            foreach ($locationname as $lkey => $locationvalue) {

                if ($subtripvalue->pick_location_id == $locationvalue->id) {
                    $subtrip[$skey]->picklocation = $locationvalue->name;
                }

                if ($subtripvalue->drop_location_id == $locationvalue->id) {
                    $subtrip[$skey]->droplocation = $locationvalue->name;
                }
            }
        }

        $couponData = array(
            "code" => $this->request->getVar('code'),
            // "subtrip_id" => $this->request->getVar('subtrip_id'),
            "start_date" => $this->request->getVar('start_date'),
            "end_date" => $this->request->getVar('end_date'),
            "discount" => $this->request->getVar('discount'),
            "discount_type" => $this->request->getVar('discount_type'),
            "condition" => $this->request->getVar('condition'),
            "coupon_for" => $this->request->getVar('coupon_type')
        );

        if ($this->validation->run($couponData, 'coupon')) {   
            // $this->couponModel->insert($couponData);
            // return redirect()->route('index-coupon')->with("success", "Data Save");

            $couponId = $this->couponModel->insert($couponData, true); 
            $couponDetailsData = [];

            $companies = $this->request->getVar('company');
            $mainTrips = $this->request->getVar('main_trips');
            $subtripsData = $this->request->getVar('subtrips');

            // Combine company IDs into a string
            $companyIdsString = implode(',', $companies);

            $groupedSubtrips = [];

            // Group subtrips by their main trip ID
            
            if (is_array($mainTrips)) {
                foreach ($mainTrips as $tripId) {
                    if (isset($subtripsData[$tripId])) {
                        $groupedSubtrips[$tripId] = $subtripsData[$tripId];
                    }
                }
            }

            // Insert each grouped entry
            foreach ($groupedSubtrips as $tripId => $subtrips) {
                $couponDetailsData[] = [
                    'coupon_id'    => $couponId,
                    'company_id'   => $companyIdsString, // Correctly stores all company IDs in one entry
                    'main_trip_id' => $tripId,
                    'sub_trip_id'  => json_encode($subtrips),
                ];
            }

            // Insert Coupon Details
            $this->couponDetailsModel->insertBatch($couponDetailsData);

            return redirect()->route('index-coupon')->with("success", "Data Saved");
                $couponId = $this->couponModel->insert($couponData, true); 

            }

        return redirect()->back()->withInput()->with('fail', $this->validation->listErrors());
    }

    public function index()
    {
        $subtrip = $this->subtripModel->withDeleted()->where('status', 1)->findAll();
        $locationname = $this->locationModel->withDeleted()->findAll();

        foreach ($subtrip as $skey => $subtripvalue) {
            foreach ($locationname as $lkey => $locationvalue) {

                if ($subtripvalue->pick_location_id == $locationvalue->id) {

                    $subtrip[$skey]->picklocation = $locationvalue->name;
                }
                if ($subtripvalue->drop_location_id == $locationvalue->id) {
                    $subtrip[$skey]->droplocation = $locationvalue->name;
                }
            }
        }

        $subtirpName = $subtrip;
        // $coupon_detail = $this->couponModel->findAll();
        $coupon_detail = $this->couponModel->getCouponsWithDetails();

        foreach ($coupon_detail as $ckey => $cvalue) {
            
            $coupon_detail[$ckey]->subtrip_name = "";
            
            foreach ($subtirpName as $skey => $svalue) {

                if ($cvalue->subtrip_id == $svalue->id) {

                    $coupon_detail[$ckey]->subtrip_name = $svalue->picklocation . '--' . $svalue->droplocation;
                }
            }
        }

        $data['module'] =    lang("Localize.coupon");
        $data['title']  =    lang("Localize.coupon_list");
        $data['coupon'] = $coupon_detail;
        $data['pageheading'] = lang("Localize.coupon_list");

        $rolepermissionLibrary = new Rolepermission();
        $add_data = "add_coupon";
        $list_data = "coupon_list";

        $data['add_data'] = $rolepermissionLibrary->create($add_data);
        $data['edit_data'] = $rolepermissionLibrary->edit($list_data);
        $data['delete_data'] = $rolepermissionLibrary->delete($list_data);

        return view($this->Viewpath . '\coupon/index', $data);
    }

    public function edit($id)
    {
        
        $subtrip = $this->subtripModel
            ->select('subtrips.id, l1.name AS picklocation, l2.name AS droplocation')
            ->join('locations l1', 'subtrips.pick_location_id = l1.id')
            ->join('locations l2', 'subtrips.drop_location_id = l2.id')
            ->where('l1.deleted_at IS NULL')
            ->where('l2.deleted_at IS NULL')
            ->where('status', 1)
            ->findAll();
        
        if(session()->get('role_id') == 7 ){
            $selectedCompanies = (array) session()->get('company_id');
        }else{
            $selectedCompanies = $this->couponDetailsModel
                ->where('coupon_id', $id)
                ->findColumn('company_id');
        }

        // Ensure `$selectedCompanies` is always an array
        $selectedCompanies = is_array($selectedCompanies) ? $selectedCompanies : [];
        

        // Handle comma-separated data if required
        if (!empty($selectedCompanies)) {
            $selectedCompanies = explode(',', implode(',', $selectedCompanies));
        }

        if (!empty($selectedCompanies)) {
            $selectedCompanies = explode(',', implode(',', $selectedCompanies));
        }

        
        if(session()->get('role_id') == 7 ){
            $selectedCompanies = (array) session()->get('company_id');
            $main_trip_data = $this->couponDetailsModel
                ->where('coupon_id', $id)
                ->whereIn('company_id', $selectedCompanies)
                ->findAll();
        }else{
            $main_trip_data = $this->couponDetailsModel
                ->where('coupon_id', $id)
                ->findAll();
        }


        $selectedMainTrips = [];
        $selectedSubTrips = [];

        if (session()->get('role_id') == 7) {
            $companyId = session()->get('company_id');
            if (!empty($companyId)) {
                $main_trip_data = array_filter($main_trip_data, function ($trip) use ($companyId) {
                    // Ensure proper matching by using regex for exact value match
                    return preg_match('/\b' . preg_quote($companyId, '/') . '\b/', $trip['company_id']);
                });
            }
        }
       
        $selectedMainTrips = array_column($main_trip_data, 'main_trip_id');
        $selectedSubTrips = array_map('strval', json_decode($main_trip_data->sub_trip_id ?? '[]', true));$selectedSubTrips = [];
        foreach ($main_trip_data as $trip) {
            $subTrips = json_decode($trip['sub_trip_id'] ?? '[]', true);
            $selectedSubTrips = array_merge($selectedSubTrips, array_map('strval', $subTrips));
        }
        
        // Fetch grouped trips using new method
        if (!empty($selectedCompanies)) {
            $groupedTrips = $this->subtripModel->getTripsByCompany($selectedCompanies);
        } else {
            $groupedTrips = [];  // Handle gracefully if no companies are selected
        }

        $data['subtrip'] = $subtrip;
        $data['coupon'] = $this->couponModel->find($id);
        $data['selectedCompanies'] = $selectedCompanies;
        $data['selectedMainTrips'] = $selectedMainTrips;
        $data['selectedSubTrips'] = $selectedSubTrips;

        $data['module'] = lang("Localize.coupon");
        $data['title'] = lang("Localize.coupon_list");

        $heading = lang("Localize.edit") . ' ' . lang("Localize.coupon");
        $data['pageheading'] = $heading;
        $data['roleId'] = session()->get('role_id');
        $data['companies'] = $this->companyModel->findAll();
        $data['trips'] = $groupedTrips;

        return view($this->Viewpath . '\coupon/edit', $data);
    }


    public function update($id)
    {
       
        $companies = (array) $this->request->getVar('company');
        $companyIdsString = implode(',', $companies);
       
        $couponData = [
            "id" => $id,
            "code" => $this->request->getVar('code'),
            "start_date" => $this->request->getVar('start_date'),
            "end_date" => $this->request->getVar('end_date'),
            "discount" => $this->request->getVar('discount'),
            "discount_type" => $this->request->getVar('discount_type'),
            "condition" => $this->request->getVar('condition'),
            "coupon_for" => $this->request->getVar('coupon_type')
        ];

        if ($this->validation->run($couponData, 'coupon')) {
            $this->couponModel->save($couponData);
            $this->couponDetailsModel->where('coupon_id', $id)->delete();

            /* --------------- */
            $couponDetailsData = [];
            $groupedSubtrips = [];

            $mainTrips = $this->request->getVar('main_trips');
            $subtripsData = $this->request->getVar('subtrips');

            // Combine company IDs into a string
            $companyIdsString = implode(',', $companies);

            // Group subtrips by their main trip ID
            
            if (is_array($mainTrips)) {
                foreach ($mainTrips as $tripId) {
                    if (isset($subtripsData[$tripId])) {
                        $groupedSubtrips[$tripId] = $subtripsData[$tripId];
                    }
                }
            }

            // Insert each grouped entry
            foreach ($groupedSubtrips as $tripId => $subtrips) {
                $couponDetailsData[] = [
                    'coupon_id'    => $id,
                    'company_id'   => $companyIdsString, // Correctly stores all company IDs in one entry
                    'main_trip_id' => $tripId,
                    'sub_trip_id'  => json_encode($subtrips),
                ];
            }
            // Insert Coupon Details
            $this->couponDetailsModel->insertBatch($couponDetailsData);
            /* --------------- */
            /* $groupedSubtrips = [];
            $couponDetailsData = [];
            $mainTrips = (array) $this->request->getVar('main_trips');
            $subtripsData = (array) $this->request->getVar('subtrips');
            
            if (session()->get('role_id') == 7) {
                foreach ($mainTrips as $tripId) {
                    $groupedSubtrips[$tripId] = $subtripsData;
                }
            } else if (session()->get('role_id') == 1) {
                foreach ($mainTrips as $tripId) {
                    if (isset($subtripsData[$tripId])) {
                        $groupedSubtrips[$tripId] = $subtripsData[$tripId];
                    }
                }
            }
           
            foreach ($groupedSubtrips as $tripId => $subtrips) {
                $couponDetailsData[] = [
                    'coupon_id'    => $id,
                    'company_id'   => $companyIdsString,
                    'main_trip_id' => $tripId,
                    'sub_trip_id'  => json_encode($subtrips),
                ];
            }

            if (!empty($couponDetailsData)) {
                $this->couponDetailsModel->insertBatch($couponDetailsData);
            } */

            return redirect()->route('index-coupon')->with("success", "Data Updated");
        }

        return redirect()->back()->withInput()->with('fail', $this->validation->listErrors());
    }


    public function delete($id)
    {
        $this->couponModel->delete($id);
        return redirect()->route('index-coupon')->with("fail", "Data Deleted");
    }

    public function getTripsByCompany()
    {
        $companyIds = $this->request->getGet('companyIds');

        if (!$companyIds) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'No company IDs provided'
            ]);
        }

        $tripData = $this->subtripModel->getTripsByCompany($companyIds);

        return $this->response->setJSON([
            'success' => true,
            'data' => $tripData
        ]);
    }
        public function serverList()
    {
        $request = service('request');

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

        // Check permissions
        $rolepermissionLibrary = new Rolepermission();
        $edit_coupon = $rolepermissionLibrary->edit("coupon_list");
        $delete_coupon = $rolepermissionLibrary->delete("coupon_list");

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

        // Column map
        $columns = [
            0 => 'coupons.id',
            1 => 'coupons.coupon_for',
            2 => 'companies.name',
            3 => 'coupons.code',
            4 => 'coupons.start_date',
            5 => 'coupons.end_date',
            6 => 'coupons.discount',
            7 => null, // subtrip_name - computed field
            8 => 'coupons.condition',
            9 => null  // action column
        ];

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

        // ---- TOTAL RECORDS ----
        $totalBuilder = $this->db->table('coupons');
        $totalBuilder->select('coupons.id')
            ->join('coupon_details', 'coupon_details.coupon_id = coupons.id', 'left')
            ->join('companies', 'FIND_IN_SET(companies.id, coupon_details.company_id)', 'left')
            ->where('coupons.deleted_at IS NULL')
            ->groupBy('coupons.id');
        
        // Apply role-based filtering for total count
        if ($role_id != 1) {
            $totalBuilder->where('companies.id', $company_id);
        }
        
        $totalRecords = $totalBuilder->countAllResults(false);

        // Create fresh builder for filtered query
        $builder = $this->db->table('coupons');
        $builder->select('
                coupons.*,
                GROUP_CONCAT(DISTINCT companies.name SEPARATOR ", ") AS company_names,
                GROUP_CONCAT(DISTINCT coupon_details.sub_trip_id SEPARATOR "|||") AS all_sub_trip_ids
            ')
            ->join('coupon_details', 'coupon_details.coupon_id = coupons.id', 'left')
            ->join('companies', 'FIND_IN_SET(companies.id, coupon_details.company_id)', 'left')
            ->where('coupons.deleted_at IS NULL')
            ->groupBy('coupons.id');

        // Apply role-based filtering
        if ($role_id != 1) {
            $builder->where('companies.id', $company_id);
        }

        // Global search
        if (!empty($searchValue)) {
            $builder->groupStart()
                ->like('coupons.code', $searchValue)
                ->orLike('coupons.start_date', $searchValue)
                ->orLike('coupons.end_date', $searchValue)
                ->orLike('coupons.discount', $searchValue)
                ->orLike('coupons.condition', $searchValue)
                ->orLike('companies.name', $searchValue)
                ->groupEnd();
        }

        // Column-wise filters
        if (!empty($request->getPost('columns'))) {
            foreach ($request->getPost('columns') as $idx => $col) {
                $searchCol = $col['search']['value'] ?? '';
                if ($searchCol !== '' && isset($columns[$idx]) && $columns[$idx] !== null) {
                    $builder->like($columns[$idx], $searchCol);
                }
            }
        }

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

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

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

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

        // Get all subtrips with location names for subtrip_name computation
        $subtripsQuery = $this->db->table('subtrips')
            ->select('subtrips.id, l1.name AS picklocation, l2.name AS droplocation')
            ->join('locations l1', 'subtrips.pick_location_id = l1.id', 'left')
            ->join('locations l2', 'subtrips.drop_location_id = l2.id', 'left')
            ->where('subtrips.status', 1)
            ->where('l1.deleted_at IS NULL')
            ->where('l2.deleted_at IS NULL');
        
        $allSubtrips = $subtripsQuery->get()->getResult();
        
        // Create a lookup array for quick access
        $subtripsMap = [];
        foreach ($allSubtrips as $st) {
            $subtripsMap[$st->id] = $st->picklocation . '--' . $st->droplocation;
        }

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

        foreach ($records as $row) {
            // Get subtrip name from coupon_details
            $subtripName = "";
            if (!empty($row->all_sub_trip_ids)) {
                // Split multiple sub_trip_id JSON strings
                $subTripIdStrings = explode("|||", $row->all_sub_trip_ids);
                $allSubtripIds = [];
                
                foreach ($subTripIdStrings as $subTripIdString) {
                    $subTripIds = json_decode($subTripIdString, true);
                    if (is_array($subTripIds) && !empty($subTripIds)) {
                        $allSubtripIds = array_merge($allSubtripIds, $subTripIds);
                    }
                }
                
                // Remove duplicates and get unique subtrip names
                $allSubtripIds = array_unique($allSubtripIds);
                $subtripNames = [];
                foreach ($allSubtripIds as $stId) {
                    if (isset($subtripsMap[$stId])) {
                        $subtripNames[] = $subtripsMap[$stId];
                    }
                }
                $subtripName = !empty($subtripNames) ? implode(", ", array_unique($subtripNames)) : "";
            }

            // Format coupon_for
            $couponFor = "";
            if ($row->coupon_for == 1) {
                $couponFor = "Online";
            } elseif ($row->coupon_for == 0) {
                $couponFor = "Agent";
            }

            $data[] = [
                "index" => $i++,
                "coupon_for" => $couponFor,
                "company" => esc($row->company_names ?? ''),
                "code" => esc($row->code),
                "start_date" => esc($row->start_date),
                "end_date" => esc($row->end_date),
                "discount" => esc($row->discount),
                "subtrip_name" => $subtripName,
                "condition" => esc($row->condition ?? ''),
                "action" => $this->generateActionButtons($row, $edit_coupon, $delete_coupon)
            ];
        }

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

    private function generateActionButtons($row, $edit_coupon, $delete_coupon)
    {
        $security = \Config\Services::security();
        $csrfToken = $security->getTokenName();
        $csrfHash = $security->getHash();
        
        $actionHtml = '';
        
        if ($edit_coupon) {
            $actionHtml .= '<a href="' . base_url(route_to('edit-coupon', $row->id)) . '" class="btn btn-sm btn-info text-white" title="' . lang("Localize.edit") . '"><i class="fas fa-edit"></i></a> ';
        }
        
        if ($delete_coupon) {
            $actionHtml .= '<form action="' . base_url(route_to('ss-delete-confirmation', 'coupon', $row->id)) . '" method="get" class="d-inline-block deletionForm">';
            $actionHtml .= '<button type="button" data-modal-confirm="true" class="btn btn-sm btn-danger" title="' . lang("Localize.delete") . '"><i class="far fa-trash-alt"></i></button>';
            $actionHtml .= '</form>';
        }
        
        return $actionHtml;
    }
}
