<?php

namespace Modules\Passanger\Controllers;

use App\Controllers\BaseController;
use Modules\User\Models\UserModel;
use Modules\User\Models\UserDetailModel;
use Modules\Role\Models\RoleModel;
use CodeIgniter\API\ResponseTrait;
use Modules\Company\Models\CompanyModel;

use App\Libraries\Rolepermission;

class Passanger extends BaseController
{

    protected $Viewpath;
    protected $userModel;
    protected $userDetailModel;
    protected $roleModel;
    protected $db;
    protected $companyModel;

    use ResponseTrait;


    public function __construct()
    {

        $this->Viewpath = "Modules\Passanger\Views";
        $this->userModel = new UserModel();
        $this->userDetailModel = new UserDetailModel();
        $this->roleModel = new RoleModel();
        $this->db = \Config\Database::connect();
        $this->companyModel = new CompanyModel();
    }


    public function new()
    {
        $builder = $this->db->table('country');
        $query   = $builder->get();
        $data['country'] = $query->getResult();


        $data['module'] =    lang("Localize.passanger");
        $data['title']  =    lang("Localize.add_passanger");

        $data['pageheading'] = lang("Localize.add_passanger");
        $data['companies'] = $this->companyModel->findAll();

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

    // public function index2(bool $showTrashOnly = false)
    // {
    //     // build layout data
    //     $data['module'] = lang("Localize.passanger");
    //     $data['title']  = lang("Localize.passanger_list");
    //     $data['pageheading'] = lang("Localize.passanger_list");

    //     // build role permissions
    //     $rolepermissionLibrary = new Rolepermission();
    //     $data['add_data'] = $rolepermissionLibrary->create("add_passanger");
    //     $data['edit_data'] = $rolepermissionLibrary->edit("passanger_list");
    //     $data['delete_data'] = $rolepermissionLibrary->delete("add_passanger");

    //     // get country list
    //     $data['country'] = $this->db->table('country')->get()->getResult();

    //     // capture search term (server-side search across all passengers)
    //     $search = $this->request->getGet('search');
    //     $data['search'] = $search;

    //     // build user list (paginated to avoid loading all records at once)
    //     if (session()->get('role_id') == "1") {
    //         $this->userModel
    //             ->select('users.id as user_id, users.*, user_details.*, companies.name')
    //             ->join('user_details', 'user_details.user_id = users.id', 'left')
    //             ->join('tickets', 'tickets.passanger_id = user_details.user_id', 'left')
    //             ->join('trips', 'tickets.trip_id = trips.id', 'left')
    //             ->join('companies', 'trips.company_id = companies.id', 'left')
    //             ->where('role_id', 3)
    //             ->orderBy('users.id', 'DESC');
    //     } elseif (session()->get('company_id') > 0) {
    //         $this->userModel
    //             ->select('users.id as user_id, users.*, user_details.*, companies.name')
    //             ->join('user_details', 'user_details.user_id = users.id', 'left')
    //             ->join('tickets', 'tickets.passanger_id = user_details.user_id', 'left')
    //             ->join('trips', 'tickets.trip_id = trips.id', 'left')
    //             ->join('companies', 'companies.id = trips.company_id', 'left')
    //             ->where('role_id', 3)
    //             ->where('trips.company_id', session()->get('company_id'))
    //             ->orderBy('users.id', 'DESC');
    //     } else {
    //         $this->userModel
    //             ->select('users.id as user_id, users.*, user_details.*, companies.name')
    //             ->join('user_details', 'user_details.user_id = users.id', 'left')
    //             ->join('companies', 'user_details.company_id = companies.id', 'left')
    //             ->where('role_id', 3)
    //             ->orderBy('users.id', 'DESC');
    //     }

    //     // apply global search if provided
    //     if (!empty($search)) {
    //         $this->userModel
    //             ->groupStart()
    //                 ->like('user_details.first_name', $search)
    //                 ->orLike('user_details.last_name', $search)
    //                 ->orLike('users.login_email', $search)
    //                 ->orLike('users.login_mobile', $search)
    //             ->groupEnd();
    //     }

    //     if ($showTrashOnly) {
    //         $data['trash_view'] = true;
    //         $this->userModel->onlyDeleted();
    //     }

    //     // Use pagination instead of loading every passenger into memory.
    //     // This keeps the page fast even when there are many thousands of records.
    //     $perPage = 50; // number of passengers per page
    //     $data['userDetail'] = $this->userModel->paginate($perPage);
    //     $data['pager'] = $this->userModel->pager;
    //     $data['companies'] = $this->companyModel->findAll();
    //     //dd($data['userDetail']);
    //     return view($this->Viewpath . '\passanger\index', $data);
    // }
public function index(bool $showTrashOnly = false)
{
    // layout data
    $data['module'] = lang("Localize.passanger");
    $data['title']  = lang("Localize.passanger_list");
    $data['pageheading'] = lang("Localize.passanger_list");

    // role permissions — super admin (role_id 1) always has full access
    $rolepermissionLibrary = new Rolepermission();
    $isSuperAdmin = ((int) session()->get('role_id') === 1);
    $data['add_data']    = $isSuperAdmin || $rolepermissionLibrary->create("add_passanger");
    $data['edit_data']   = $isSuperAdmin || $rolepermissionLibrary->edit("passanger_list");
    $data['delete_data'] = $isSuperAdmin
        || $rolepermissionLibrary->delete("add_passanger")
        || $rolepermissionLibrary->delete("passanger_list");

    // country list
    $data['country'] = $this->db->table('country')->get()->getResult();

    // search capture
    $search = $this->request->getGet('search');
    $data['search'] = $search;

    // ---- BASE SELECT (only required columns) ----
    $this->userModel
        ->select("
            users.id,
            users.created_at,
            users.login_email,
            users.login_mobile,
            users.deleted_at,
            user_details.first_name,
            user_details.last_name,
            GROUP_CONCAT(DISTINCT companies.name ORDER BY companies.name SEPARATOR ', ') AS company_names
        ")
        ->join('user_details', 'user_details.user_id = users.id', 'left')
        ->where('users.role_id', 3);

    // ---- ROLE-BASED LOGIC ----

    if (session()->get('role_id') == "1") {

        // super admin → see all
        $this->userModel
            ->join('tickets', 'tickets.passanger_id = users.id', 'left')
            ->join('trips', 'trips.id = tickets.trip_id', 'left')
            ->join('companies', 'companies.id = trips.company_id', 'left');

    } elseif (session()->get('company_id') > 0) {

        // company admin → see their passengers only
        $this->userModel
            ->join('tickets', 'tickets.passanger_id = users.id', 'left')
            ->join('trips', 'trips.id = tickets.trip_id', 'left')
            ->join('companies', 'companies.id = trips.company_id', 'left')
            ->where('trips.company_id', session()->get('company_id'));

    } else {

        // neither admin nor company admin
        $this->userModel
            ->join('companies', 'user_details.company_id = companies.id', 'left');
    }

    // GROUP BY needed due to GROUP_CONCAT
    $this->userModel->groupBy('users.id');

    // ---- SEARCH ----
    if (!empty($search)) {
        $this->userModel
            ->groupStart()
                ->like('user_details.first_name', $search)
                ->orLike('user_details.last_name', $search)
                ->orLike('users.login_email', $search)
                ->orLike('users.login_mobile', $search)
            ->groupEnd();
    }

    // ---- Trash View ----
    if ($showTrashOnly) {
        $data['trash_view'] = true;
        $this->userModel->onlyDeleted();
    }

    // ---- PAGINATION ----
    $perPage = 50;
    $data['userDetail'] = $this->userModel->paginate($perPage);
    $data['pager'] = $this->userModel->pager;

    $data['companies'] = $this->companyModel->findAll();

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

    /**
     * Export all passengers (optionally filtered by search term) as CSV.
     */
    public function exportAll()
    {
        $search = $this->request->getGet('search');

        // base query (same as index list, without pagination)
        if (session()->get('role_id') == "1") {
            $this->userModel
                ->select('users.id as user_id, users.*, user_details.*, companies.name')
                ->join('user_details', 'user_details.user_id = users.id', 'left')
                ->join('tickets', 'tickets.passanger_id = user_details.user_id', 'left')
                ->join('trips', 'tickets.trip_id = trips.id', 'left')
                ->join('companies', 'trips.company_id = companies.id', 'left')
                ->where('role_id', 3)
                ->orderBy('users.id', 'DESC');
        } elseif (session()->get('company_id') > 0) {
            $this->userModel
                ->select('users.id as user_id, users.*, user_details.*, companies.name')
                ->join('user_details', 'user_details.user_id = users.id', 'left')
                ->join('tickets', 'tickets.passanger_id = user_details.user_id', 'left')
                ->join('trips', 'tickets.trip_id = trips.id', 'left')
                ->join('companies', 'companies.id = trips.company_id', 'left')
                ->where('role_id', 3)
                ->where('trips.company_id', session()->get('company_id'))
                ->orderBy('users.id', 'DESC');
        } else {
            $this->userModel
                ->select('users.id as user_id, users.*, user_details.*, companies.name')
                ->join('user_details', 'user_details.user_id = users.id', 'left')
                ->join('companies', 'user_details.company_id = companies.id', 'left')
                ->where('role_id', 3)
                ->orderBy('users.id', 'DESC');
        }

        if (!empty($search)) {
            $this->userModel
                ->groupStart()
                    ->like('user_details.first_name', $search)
                    ->orLike('user_details.last_name', $search)
                    ->orLike('users.login_email', $search)
                    ->orLike('users.login_mobile', $search)
                ->groupEnd();
        }

        $rows = $this->userModel->findAll();

        $fp = fopen('php://temp', 'r+');
        fputcsv($fp, ['#', 'Name', 'Joined At', 'Email', 'Company', 'Mobile']);

        $i = 1;
        foreach ($rows as $row) {
            $fullName = trim(($row->first_name ?? '') . ' ' . ($row->last_name ?? ''));
            fputcsv($fp, [
                $i++,
                $fullName,
                $row->created_at,
                $row->login_email,
                $row->name ?? '',
                $row->login_mobile,
            ]);
        }

        rewind($fp);
        $csv = stream_get_contents($fp);
        fclose($fp);

        return $this->response
            ->setHeader('Content-Type', 'text/csv')
            ->setHeader('Content-Disposition', 'attachment; filename="passengers_' . date('Ymd_His') . '.csv"')
            ->setBody($csv);
    }
    
    
    public function create()
    {
        // Build new user model data
        $login_email = $this->request->getVar('login_email');
        $login_mobile =  $this->request->getVar('login_mobile');
        $password = $this->request->getVar('password');
        $confirm = $this->request->getVar('confirm_password');
        $companyId = $this->request->getVar('company_id')??session()->get('company_id');

        $userData = array(
            "login_email" => $login_email,
            "login_mobile" => $login_mobile,
            "password" => $password,
            "confirm" => $confirm,
            "slug" => bin2hex(random_bytes(5)),
            "role_id" => 3,
            "status" => 1
        );

        if ($this->validation->run($userData, 'user')) {
            $this->db->transStart();

            // build hashed passowrd
            // and insert to user model
            $userData['password'] = password_hash($password, PASSWORD_BCRYPT);
            $userId = $this->userModel->insert($userData);

            // build user detail model data
            $userDetailData = array(
                "user_id" => $userId,
                "company_id" => $companyId,
                "first_name" => $this->request->getVar('first_name'),
                "last_name" => $this->request->getVar('last_name'),
                "country_id" => $this->request->getVar('country_id'),
                "address" => $this->request->getVar('address') ?? "",
                "city" => $this->request->getVar('city'),
                "zip_code" => $this->request->getVar('zip_code'),
            );

            // use id type and id number
            ($idType = $this->request->getVar('id_type')) && $userDetailData['id_type'] = $idType;
            ($idNumber = $this->request->getVar('id_number')) && $userDetailData['id_number'] = $idNumber;

            if ($this->validation->run($userDetailData, 'userDetail')) {
                // user detail data is valid
                // insert data to user details model
                $this->userDetailModel->insert($userDetailData);

                $this->db->transComplete();
                return redirect()->route('index-passanger')->with("success", "Data Save");
            }
        }

        // data is invlaid 
        // rollback database query
        return redirect()->back()->withInput()->with('fail', $this->validation->listErrors());
    }

    public function edit($id)
    {
        $builder = $this->db->table('country');
        $query   = $builder->get();
        $data['country'] = $query->getResult();
        $data['passanger'] = $this->userDetailModel->find($id);
        $userid = $data['passanger']->user_id;
        $data['passenger'] = $this->userModel->find($userid);
        $data['company_id'] = $data['passanger']->company_id;
        $data['companies'] = $this->companyModel->findAll();

        $data['module'] =    lang("Localize.passanger");
        $data['title']  =    lang("Localize.passanger_list");

        $heading = lang("Localize.passanger") . ' ' . lang("Localize.edit");
        $data['pageheading'] = $heading;

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

    public function update($id)
    {
        $companyId = $this->request->getVar('company_id')??session()->get('company_id');
        $userDetailsData = array(
            "id" => $id,
            "user_id" => $this->request->getVar('user_id'),
            "company_id" => $companyId,
            "first_name" => $this->request->getVar('first_name'),
            "last_name" => $this->request->getVar('last_name'),
            "country_id" => $this->request->getVar('country_id'),
            "id_type" => $this->request->getVar('id_type') ?: null,
            "id_number" => $this->request->getVar('id_number') ?: null,
            "address" => $this->request->getVar('address')??"",
            "city" => $this->request->getVar('city'),
            "zip_code" => $this->request->getVar('zip_code'),
        );

        if ($this->validation->run($userDetailsData, 'userDetail')) {
            $this->userDetailModel->save($userDetailsData);
            return redirect()->route('index-passanger')->with("success", "Data Save");
        }

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

    public function delete($id)
    {
        $roleId = (int) session()->get('role_id');
        $rolepermissionLibrary = new Rolepermission();
        $canDelete = $roleId === 1
            || $rolepermissionLibrary->delete('add_passanger')
            || $rolepermissionLibrary->delete('passanger_list');

        if (! $canDelete) {
            return redirect()->back()->with('fail', 'You do not have permission to delete passengers.');
        }

        $passangerInfo = $this->userDetailModel->find($id);
        if (empty($passangerInfo)) {
            return redirect()->back()->with('fail', 'Passenger not found.');
        }

        $passangerUserId = $passangerInfo->user_id;
        $passangerLastName = $passangerInfo->last_name;

        try {
            $this->db->transStart();
            $this->userDetailModel->delete($id);
            $this->userModel->delete($passangerUserId);
            $this->db->transComplete();
        } catch (\Throwable $e) {
            return redirect()->back()->with('fail', $e->getMessage());
        }

        return redirect()->back()->with('fail', "Passanger: {$passangerLastName} deleted");
    }

    public function restore($id)
    {
        $passangerInfo = $this->userDetailModel->withDeleted()->find($id);
        $passangerUserId = $passangerInfo->user_id;
        $passangerLastName = $passangerInfo->last_name;

        try {
            $this->db->transStart();
            $this->userDetailModel->set('deleted_at', null)->update($id);
            $this->userModel->set('deleted_at', null)->update($passangerUserId);
            $this->db->transComplete();
        } catch (\Throwable $e) {
            return redirect()->back()->with('fail', $e->getMessage());
        }

        return redirect()->route('trash-index-passanger')->with('success', "Passanger: {$passangerLastName} restored");
    }
        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 — super admin (role_id 1) always has full access
        $rolepermissionLibrary = new Rolepermission();
        $isSuperAdmin = ((int) $role_id === 1);
        $edit_passanger = $isSuperAdmin || $rolepermissionLibrary->edit("passanger_list");
        $delete_passanger = $isSuperAdmin || $rolepermissionLibrary->delete("add_passanger")
            || $rolepermissionLibrary->delete("passanger_list");

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

        // Column map
        // For role_id == 1: #, Name, Joined At, Email, Company, Mobile, Action
        // For role_id != 1: #, Name, Joined At, Email, Mobile, Action
        $columns = [];
        $colIndex = 0;
        
        $columns[$colIndex++] = 'users.id';  // index column
        $columns[$colIndex++] = 'user_details.first_name';  // name column
        $columns[$colIndex++] = 'users.created_at';  // joined_at
        $columns[$colIndex++] = 'users.login_email';  // email
        if ($role_id == "1") {
            $columns[$colIndex++] = 'companies.name';  // company column (only for admin)
        }
        $columns[$colIndex++] = 'users.login_mobile';  // mobile
        $columns[$colIndex++] = null;  // action column (not orderable/searchable)

        // 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('users');
        $totalBuilder->select('users.id')
            ->join('user_details', 'user_details.user_id = users.id', 'left')
            ->where('users.role_id', 3)
            ->where('users.deleted_at IS NULL');

        // Apply role-based filtering for total count
        if ($role_id == "1") {
            // super admin → see all
            $totalBuilder
                ->join('tickets', 'tickets.passanger_id = users.id', 'left')
                ->join('trips', 'trips.id = tickets.trip_id', 'left')
                ->join('companies', 'companies.id = trips.company_id', 'left');
        } elseif ($company_id > 0) {
            // company admin → see their passengers only
            $totalBuilder
                ->join('tickets', 'tickets.passanger_id = users.id', 'left')
                ->join('trips', 'trips.id = tickets.trip_id', 'left')
                ->join('companies', 'companies.id = trips.company_id', 'left')
                ->where('trips.company_id', $company_id);
        } else {
            // neither admin nor company admin
            $totalBuilder
                ->join('companies', 'user_details.company_id = companies.id', 'left');
        }

        $totalBuilder->groupBy('users.id');
        $totalRecords = $totalBuilder->countAllResults(false);

        // Create fresh builder for filtered query
        $builder = $this->db->table('users');
        $builder->select("
                users.id AS user_id,
                users.created_at,
                users.login_email,
                users.login_mobile,
                users.deleted_at,
                user_details.id AS detail_id,
                user_details.first_name,
                user_details.last_name,
                GROUP_CONCAT(DISTINCT companies.name ORDER BY companies.name SEPARATOR ', ') AS company_names
            ")
            ->join('user_details', 'user_details.user_id = users.id', 'left')
            ->where('users.role_id', 3)
            ->where('users.deleted_at IS NULL');

        // Apply role-based filtering
        if ($role_id == "1") {
            // super admin → see all
            $builder
                ->join('tickets', 'tickets.passanger_id = users.id', 'left')
                ->join('trips', 'trips.id = tickets.trip_id', 'left')
                ->join('companies', 'companies.id = trips.company_id', 'left');
        } elseif ($company_id > 0) {
            // company admin → see their passengers only
            $builder
                ->join('tickets', 'tickets.passanger_id = users.id', 'left')
                ->join('trips', 'trips.id = tickets.trip_id', 'left')
                ->join('companies', 'companies.id = trips.company_id', 'left')
                ->where('trips.company_id', $company_id);
        } else {
            // neither admin nor company admin
            $builder
                ->join('companies', 'user_details.company_id = companies.id', 'left');
        }

        // GROUP BY needed due to GROUP_CONCAT
        $builder->groupBy('users.id');

        // Global search
        if (!empty($searchValue)) {
            $builder->groupStart()
                ->like('user_details.first_name', $searchValue)
                ->orLike('user_details.last_name', $searchValue)
                ->orLike('users.login_email', $searchValue)
                ->orLike('users.login_mobile', $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('users.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) {
            // Build data array - always start with index
            $rowData = [
                "index" => $i++,
                "name" => esc($row->first_name . ' ' . $row->last_name),
                "joined_at" => esc($row->created_at ?? ''),
                "email" => esc($row->login_email ?? ''),
            ];

            // Add company column only for role_id == 1
            if ($role_id == "1") {
                $rowData["company"] = esc($row->company_names ?? '');
            }

            // Add common columns
            $rowData["mobile"] = esc($row->login_mobile ?? '');
            $rowData["action"] = $this->generateActionButtons($row, $edit_passanger, $delete_passanger);

            $data[] = $rowData;
        }

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

    private function generateActionButtons($row, $edit_passanger, $delete_passanger)
    {
        $actionHtml = '';
        
        if ($row->deleted_at == null) {
            if ($edit_passanger) {
                $actionHtml .= '<a href="' . base_url(route_to('edit-passanger', (int)$row->detail_id)) . '" class="btn btn-sm btn-info text-white" title="' . lang("Localize.edit") . '">';
                $actionHtml .= '<i class="fas fa-edit"></i>';
                $actionHtml .= '</a> ';
            }

            if ($delete_passanger && ! empty($row->detail_id)) {
                $actionHtml .= '<form action="' . base_url(route_to('delete-passanger', (int) $row->detail_id)) . '" method="post" class="deletionForm d-inline-block" accept-charset="utf-8">';
                $actionHtml .= csrf_field();
                $actionHtml .= '<input type="hidden" name="_method" value="DELETE">';
                $actionHtml .= '<button type="button" data-modal-confirm="true" class="btn btn-sm btn-danger" title="' . lang("Localize.delete") . '">';
                $actionHtml .= '<i class="far fa-trash-alt"></i>';
                $actionHtml .= '</button>';
                $actionHtml .= '</form>';
            }
        } else {
            if ($delete_passanger) {
                $actionHtml .= '<a href="' . base_url(route_to('restore-passanger', $row->detail_id)) . '" class="btn btn-sm btn-success text-white" title="' . lang("Localize.restore") . '">';
                $actionHtml .= '<i class="fas fa-undo-alt"></i> ' . lang("Localize.restore");
                $actionHtml .= '</a>';
            }
        }
        
        return $actionHtml;
    }
}
