<?php
if ( ! defined( 'ABSPATH' ) ) exit;

use Twilio\Rest\Client;
use Twilio\Jwt\AccessToken;
use Twilio\Jwt\Grants\VideoGrant;

class DialBunnyDashboardController
{
  // Update the managed phone number settings (dialbunny_phone_details)
  function update_router_table()
  {
    if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { return; }
    global $wpdb;

    $user_id = get_current_user_id();
    $table = $wpdb->prefix . 'dialbunny_phone_details';
    $now = current_time('mysql', 1);

    // Check if user has existing row
    // Direct database query used below – $wpdb->prepare() is always used to prevent SQL injection.
    $exists = $wpdb->get_var($wpdb->prepare("SELECT 1 FROM {$wpdb->prefix}dialbunny_phone_details WHERE user = %d LIMIT 1", $user_id)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery

    // Build business hours object
    $days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
    $businessHours = new stdClass();

    foreach ($days as $day) {
      if (isset($_POST["{$day}_status"]) && isset($_POST["{$day}1"]) && isset($_POST["{$day}2"]))
      {
        $status = sanitize_text_field(wp_unslash($_POST["{$day}_status"] ?? ''));
        $t1 = sanitize_text_field(wp_unslash($_POST["{$day}1"] ?? ''));
        $t2 = sanitize_text_field(wp_unslash($_POST["{$day}2"] ?? ''));
          $businessHours->{"{$day}_status"} = $status;
          $businessHours->{"{$day}1"} = $t1;
          $businessHours->{"{$day}2"} = $t2;
      }
    }

    $data = [
      'updated_at' => $now,
    ];

    // Sanitize and assign contact numbers
    for ($i = 1; $i <= 3; $i++) {
      if (isset($_POST["call{$i}"])) {
        $number = preg_replace('/[^0-9]/', '', sanitize_text_field(wp_unslash($_POST["call{$i}"])));
        $code = sanitize_text_field(wp_unslash($_POST["countrycode{$i}"] ?? ''));
        $data["call{$i}"] = $code . '-' . $number;
        $data["call{$i}_verified"] = 0;
      }
    }

    $data['user'] = $user_id;
    if (isset($_POST['timezone'])) {
      $data['timezone'] = sanitize_text_field(wp_unslash($_POST['timezone']));
    }
    if (isset($businessHours)) {
      $myJSON = wp_json_encode($businessHours);
      if (strlen($myJSON) > 9) { $data['business_hours'] = $myJSON; }
    }
    if (isset($_POST['welcome'])) {
      $data['welcome'] = sanitize_textarea_field(wp_unslash($_POST['welcome']));
    }
    if (isset($_POST['busy'])) {
      $data['busy'] = sanitize_textarea_field(wp_unslash($_POST['busy']));
    }
    if (isset($_POST['outside_hours_message'])) {
      $data['outside_hours_message'] = sanitize_textarea_field(wp_unslash($_POST['outside_hours_message']));
    }

    if (! $exists) {
      $data['id'] = uniqid();
      $data['created_at'] = $now;
      // Direct database query used below – Safely inserts data into the database using $wpdb->insert(), which handles proper escaping and prevents SQL injection.
      $wpdb->insert($table, $data); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    } else {
      // Direct database query used below – Safely updates data into the database using $wpdb->update(), which handles proper escaping and prevents SQL injection.
      $wpdb->update($table, $data, ['user' => $user_id]); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    }

    // Safe redirect
    $user_nonce = sanitize_text_field(wp_unslash($_POST['user_nonce']));
    $redirect_url = admin_url('admin.php?page=dialbunny_dashboard');
    if (! empty($_POST['dashboardpage'])) {
      $dashboard_page = sanitize_key($_POST['dashboardpage']);
      $redirect_url .= '&dashboardpage=' . urlencode($dashboard_page);
    }
    $redirect_url .= '&updated&user_nonce='.$user_nonce;
    wp_safe_redirect($redirect_url);
    exit;
  }

  // Update ai assistant settings
  function update_ai_assistant()
  {
    if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { return; }
    global $wpdb;
    $user_id = get_current_user_id();
    $table = $wpdb->prefix . 'dialbunny_phone_details';
    $now = current_time('mysql', 1);

    // Check if user has existing row
    // Direct database query used below – $wpdb->prepare() is always used to prevent SQL injection.
    $exists = $wpdb->get_var($wpdb->prepare("SELECT 1 FROM {$wpdb->prefix}dialbunny_phone_details WHERE user = %d LIMIT 1", $user_id)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery

    $data = array();
    $rawdata = array();
    $data['user'] = $user_id;
    $data['updated_at'] = $now;
    if (isset($_POST['initiated'])) { $rawdata['ai_initiated'] = sanitize_textarea_field(wp_unslash($_POST['initiated'])); } else { $rawdata['ai_initiated'] = 0; }
    if (isset($_POST['busy'])) { $rawdata['ai_busy'] = sanitize_textarea_field(wp_unslash($_POST['busy'])); } else { $rawdata['ai_busy'] = 0; }
    if (isset($_POST['timetable'])) { $rawdata['ai_timetable'] = sanitize_textarea_field(wp_unslash($_POST['timetable'])); } else { $rawdata['ai_timetable'] = 0; }
    if (isset($_POST['twilio_sid'])) { $rawdata['twilio_sid'] = str_replace(' ', '', sanitize_textarea_field(wp_unslash($_POST['twilio_sid']))); } else { $rawdata['twilio_sid'] = ''; }
    if (isset($_POST['vapi_sip'])) { $rawdata['vapi_sip'] = str_replace(' ', '', sanitize_textarea_field(wp_unslash($_POST['vapi_sip']))); } else { $rawdata['vapi_sip'] = ''; }
    if (isset($_POST['radio'])) { $rawdata['voice_company'] = sanitize_textarea_field(wp_unslash($_POST['radio'])); } else { $rawdata['voice_company'] = 'twilio'; }
    if (!empty($_POST['greeting'])) { $rawdata['greeting'] = sanitize_textarea_field(wp_unslash($_POST['greeting'])); } else { $rawdata['greeting'] = 'Hi! Ask me anything!'; }
    if (!empty($_POST['voice'])) { $rawdata['voice'] = sanitize_textarea_field(wp_unslash($_POST['voice'])); } else { $rawdata['voice'] = 'en-US-Journey-O'; }
    if (isset($_POST['messages'])) { $rawdata['ai_messages'] = sanitize_textarea_field(wp_unslash($_POST['messages'])); } else { $rawdata['ai_messages'] = 0; }
    $json_data = wp_json_encode($rawdata);
    $data['voice_assistant'] = $json_data;

    if (! $exists) {
      $data['id'] = uniqid();
      $data['created_at'] = $now;
      // Direct database query used below – Safely inserts data into the database using $wpdb->insert(), which handles proper escaping and prevents SQL injection.
      $wpdb->insert($table, $data); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    } else {
      // Direct database query used below – Safely updates data into the database using $wpdb->update(), which handles proper escaping and prevents SQL injection.
      $wpdb->update($table, $data, ['user' => $user_id]); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    }

    // Safe redirect
    $user_nonce = sanitize_text_field(wp_unslash($_POST['user_nonce']));
    $redirect_url = admin_url('admin.php?page=dialbunny_dashboard');
    if (! empty($_POST['dashboardpage'])) {
      $dashboard_page = sanitize_key($_POST['dashboardpage']);
      $redirect_url .= '&dashboardpage=' . urlencode($dashboard_page);
    }
    $redirect_url .= '&updated&user_nonce='.$user_nonce;
    wp_safe_redirect($redirect_url);
    exit;
  }

  // Search for available phone numbers
  function search_numbers()
  {
    if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { return; }

    // Sanitize input fields
    $countrycode = sanitize_text_field(wp_unslash($_POST['countrycode'] ?? ''));
    $areacode    = sanitize_text_field(wp_unslash($_POST['areacode'] ?? ''));
    $contains    = sanitize_text_field(wp_unslash($_POST['contains'] ?? ''));
    $type        = sanitize_text_field(wp_unslash($_POST['type'] ?? ''));
    $requirements= sanitize_text_field(wp_unslash($_POST['addressrequirements'] ?? ''));
    $beta        = sanitize_text_field(wp_unslash($_POST['beta'] ?? ''));
    $user_nonce  = sanitize_text_field(wp_unslash($_POST['user_nonce']));

    // Build redirect URL safely
    $redirect_url = add_query_arg([
        'page'        => 'dialbunny_dashboard',
        'dashboardpage' => 'choose',
        'countrycode' => $countrycode,
        'areacode'    => $areacode,
        'contains'    => $contains,
        'type'        => $type,
        'requirements'=> $requirements,
        'beta'        => $beta,
        'user_nonce'  => $user_nonce, // carry it forward
    ], admin_url('admin.php'));

    wp_safe_redirect($redirect_url);
    exit;
  }

  // When a user requests a phone number, - Get a phone number and add it to the database
  function request_number()
  {
    if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { return; }
    global $wpdb;
    $user_id = get_current_user_id();
    $number_raw = sanitize_text_field(wp_unslash($_POST['number'] ?? ''));
    $country_code = '';
    $phone_number = '';

    // Define known country codes and lengths
    $country_codes = [
      '+1'    => 2,   // United States, Canada, NANP countries
      '+7'    => 2,   // Russia, Kazakhstan
      '+20'   => 3,   // Egypt
      '+27'   => 3,   // South Africa
      '+30'   => 3,   // Greece
      '+31'   => 3,   // Netherlands
      '+32'   => 3,   // Belgium
      '+33'   => 3,   // France
      '+34'   => 3,   // Spain
      '+36'   => 3,   // Hungary
      '+39'   => 3,   // Italy
      '+40'   => 3,   // Romania
      '+41'   => 3,   // Switzerland
      '+43'   => 3,   // Austria
      '+44'   => 3,   // United Kingdom
      '+45'   => 3,   // Denmark
      '+46'   => 3,   // Sweden
      '+47'   => 3,   // Norway
      '+48'   => 3,   // Poland
      '+49'   => 3,   // Germany
      '+51'   => 3,   // Peru
      '+52'   => 3,   // Mexico
      '+53'   => 3,   // Cuba
      '+54'   => 3,   // Argentina
      '+55'   => 3,   // Brazil
      '+56'   => 3,   // Chile
      '+57'   => 3,   // Colombia
      '+58'   => 3,   // Venezuela
      '+60'   => 3,   // Malaysia
      '+61'   => 3,   // Australia
      '+62'   => 3,   // Indonesia
      '+63'   => 3,   // Philippines
      '+64'   => 3,   // New Zealand
      '+65'   => 3,   // Singapore
      '+66'   => 3,   // Thailand
      '+81'   => 3,   // Japan
      '+82'   => 3,   // South Korea
      '+84'   => 3,   // Vietnam
      '+86'   => 3,   // China
      '+90'   => 3,   // Turkey
      '+91'   => 3,   // India
      '+92'   => 3,   // Pakistan
      '+93'   => 3,   // Afghanistan
      '+94'   => 3,   // Sri Lanka
      '+95'   => 3,   // Myanmar
      '+98'   => 3,   // Iran'
      '+211'  => 4,   // South Sudan
      '+212'  => 4,   // Morocco
      '+213'  => 4,   // Algeria
      '+216'  => 4,   // Tunisia
      '+218'  => 4,   // Libya
      '+220'  => 4,   // Gambia
      '+221'  => 4,   // Senegal
      '+222'  => 4,   // Mauritania
      '+223'  => 4,   // Mali
      '+224'  => 4,   // Guinea
      '+225'  => 4,   // Côte d'Ivoire
      '+226'  => 4,   // Burkina Faso
      '+227'  => 4,   // Niger
      '+228'  => 4,   // Togo
      '+229'  => 4,   // Benin
      '+230'  => 4,   // Mauritius
      '+231'  => 4,   // Liberia
      '+232'  => 4,   // Sierra Leone
      '+233'  => 4,   // Ghana
      '+234'  => 4,   // Nigeria
      '+235'  => 4,   // Chad
      '+236'  => 4,   // Central African Republic
      '+237'  => 4,   // Cameroon
      '+238'  => 4,   // Cape Verde
      '+239'  => 4,   // São Tomé & Príncipe
      '+240'  => 4,   // Equatorial Guinea
      '+241'  => 4,   // Gabon
      '+242'  => 4,   // Congo (Brazzaville)
      '+243'  => 4,   // Congo (Kinshasa)
      '+244'  => 4,   // Angola
      '+245'  => 4,   // Guinea-Bissau
      '+246'  => 4,   // British Indian Ocean Territory
      '+248'  => 4,   // Seychelles
      '+249'  => 4,   // Sudan
      '+250'  => 4,   // Rwanda
      '+251'  => 4,   // Ethiopia
      '+252'  => 4,   // Somalia
      '+253'  => 4,   // Djibouti
      '+254'  => 4,   // Kenya
      '+255'  => 4,   // Tanzania
      '+256'  => 4,   // Uganda
      '+257'  => 4,   // Burundi
      '+258'  => 4,   // Mozambique
      '+260'  => 4,   // Zambia
      '+261'  => 4,   // Madagascar
      '+262'  => 4,   // Réunion / Mayotte
      '+263'  => 4,   // Zimbabwe
      '+264'  => 4,   // Namibia
      '+265'  => 4,   // Malawi
      '+266'  => 4,   // Lesotho
      '+267'  => 4,   // Botswana
      '+268'  => 4,   // Eswatini
      '+269'  => 4,   // Comoros
      '+290'  => 4,   // Saint Helena
      '+291'  => 4,   // Eritrea
      '+297'  => 4,   // Aruba
      '+298'  => 4,   // Faroe Islands
      '+299'  => 4,   // Greenland
      '+1242' => 5,   // Bahamas
      '+1246' => 5,   // Barbados
      '+1264' => 5,   // Anguilla
      '+1268' => 5,   // Antigua & Barbuda
      '+1284' => 5,   // British Virgin Islands
      '+1340' => 5,   // U.S. Virgin Islands
      '+1345' => 5,   // Cayman Islands
      '+1441' => 5,   // Bermuda
      '+1473' => 5,   // Grenada
      '+1649' => 5,   // Turks & Caicos
      '+1664' => 5,   // Montserrat
      '+1670' => 5,   // Northern Mariana Islands
      '+1671' => 5,   // Guam
      '+1684' => 5,   // American Samoa
      '+1758' => 5,   // Saint Lucia
      '+1767' => 5,   // Dominica
      '+1784' => 5,   // Saint Vincent & the Grenadines
      '+1809' => 5,   // Dominican Republic
      '+1829' => 5,   // Dominican Republic (overlay)
      '+1849' => 5,   // Dominican Republic (overlay)
      '+1868' => 5,   // Trinidad & Tobago
      '+1869' => 5,   // Saint Kitts & Nevis
      '+1876' => 5,   // Jamaica
    ];

    // Match country code from the longest to shortest
    foreach ($country_codes as $code => $length) {
      if (str_starts_with($number_raw, $code)) {
        $country_code = $code;
        $phone_number = substr($number_raw, $length); // Remove prefix
        break;
      }
    }

    // Fallback (optional)
    //if (empty($country_code) || empty($phone_number)) {
    //  wp_safe_redirect(admin_url('admin.php?page=dialbunny_dashboard&error=invalid_number'));
    //  exit;
    //}

    // Remove any non-digits from phone number
    $phone_number = preg_replace('/[^0-9]/', '', $phone_number);

    // Twilio interaction
    try {
      $keys = new DialBunnyKeysClass();
      $client = new Client($keys->TWILIO_SID(), $keys->TWILIO_TOKEN());
      $incoming_phone_number;

      // Request and purchase the phone number from TWILIO
      if (isset($_POST['addressidentity']) && sanitize_text_field(wp_unslash($_POST['addressidentity'])) == 'none') 
      {
        $incoming_phone_number = $client->incomingPhoneNumbers->create([
        "friendlyName" => wp_get_current_user()->user_login,
        "emergencyStatus" => "Inactive",
        "voiceApplicationSid" => $keys->TwiML_App_SID(),
        "smsApplicationSid" => $keys->TwiML_App_SID(),
        "smsMethod" => "POST",
        "voiceMethod" => "POST",
        "phoneNumber" => $country_code . $phone_number,
        ]);
      }
      else 
      {
        $incoming_phone_number = $client->incomingPhoneNumbers->create([
        "friendlyName" => wp_get_current_user()->user_login,
        "emergencyStatus" => "Inactive",
        "voiceApplicationSid" => $keys->TwiML_App_SID(),
        "smsApplicationSid" => $keys->TwiML_App_SID(),
        "smsMethod" => "POST",
        "voiceMethod" => "POST",
        "phoneNumber" => $country_code . $phone_number,
        "addressSid" => sanitize_text_field(wp_unslash($_POST['addressidentity'] ?? '')),
        "bundleSid" => sanitize_text_field(wp_unslash($_POST['bundleidentity'] ?? '')),
        ]);
      }
      if ($incoming_phone_number) {
        $table = $wpdb->prefix . 'dialbunny_phone_details';
        // Direct database query used below – $wpdb->prepare() is always used to prevent SQL injection.
        $existing = $wpdb->get_row($wpdb->prepare("SELECT id,managed_number_code,managed_number FROM {$wpdb->prefix}dialbunny_phone_details WHERE user = %d LIMIT 1", $user_id)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery

        $now = current_time('mysql', 1);

        $data = [
          'managed_number_code' => $country_code,
          'managed_number' => $phone_number,
          'sid' => $incoming_phone_number->sid,
          'updated_at' => $now,
        ];

        if (!$existing) {
          $data['id'] = uniqid();
          $data['user'] = $user_id;
          $data['status'] = 'active';
          $data['created_at'] = $now;
          // Direct database query used below – Safely inserts data into the database using $wpdb->insert(), which handles proper escaping and prevents SQL injection.
          $wpdb->insert($table, $data); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
        } else {
          // Direct database query used below – Safely updates data into the database using $wpdb->update(), which handles proper escaping and prevents SQL injection.
          // Move released number to the released table
          $released_table = $wpdb->prefix . 'dialbunny_released_numbers';
          $current_details = [
            'id' => uniqid(),
            'user' => $user_id,
            'countrycode' => $existing->managed_number_code,
            'phone' => $existing->managed_number,
            'sid' => $existing->sid,
            'created_at' => current_time('mysql', 1),
            'updated_at' => current_time('mysql', 1),
          ];
          $wpdb->insert($released_table, $current_details); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
          // Update the user's managed number to mark it as released
          $updated = $wpdb->update($table, $data, [ // phpcs:ignore WordPress.DB.DirectDatabaseQuery
            'managed_number' => $existing->managed_number,
            'managed_number_code' => $existing->managed_number_code,
            'user' => $user_id,
          ]);
        }

        // Redirect
        wp_safe_redirect(admin_url('admin.php?page=dialbunny_dashboard&phonenumberadded&user_nonce='.sanitize_text_field(wp_unslash($_POST['user_nonce']))));
      } else {
        wp_safe_redirect(admin_url('admin.php?page=dialbunny_dashboard&dashboardpage=choose&erroraddingnumber&user_nonce='.sanitize_text_field(wp_unslash($_POST['user_nonce']))));
      }
    } catch (Exception $e) {
      wp_safe_redirect(admin_url('admin.php?page=dialbunny_dashboard&dashboardpage=choose&addressrequired&user_nonce='.sanitize_text_field(wp_unslash($_POST['user_nonce']))));
    }
    exit;
  }

  // re-request phone number
  function re_request()
  {
    if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { return; }
    if (!isset($_POST['number']) && !isset($_POST['countrycode']) && !isset($_POST['phonesid'])) { return; }

    global $wpdb;
    $user_id = get_current_user_id();

     // Sanitize and Validate inputs
     $phone_number = sanitize_text_field(wp_unslash($_POST['number'])); if (! preg_match('/^[0-9]{4,15}$/', $phone_number)) { wp_safe_redirect(admin_url('admin.php?page=dialbunny_dashboard&dashboardpage=released&erroraddingnumber&user_nonce='.sanitize_text_field(wp_unslash($_POST['user_nonce'])))); exit; }
     $country_code = sanitize_text_field(wp_unslash($_POST['countrycode'])); if (! preg_match('/^\+?[0-9]{1,15}$/', $country_code)) { wp_safe_redirect(admin_url('admin.php?page=dialbunny_dashboard&dashboardpage=released&erroraddingnumber&user_nonce='.sanitize_text_field(wp_unslash($_POST['user_nonce'])))); exit; }
     $phone_sid = sanitize_text_field(wp_unslash($_POST['phonesid']));

     $released_table = $wpdb->prefix . 'dialbunny_released_numbers';
     $table = $wpdb->prefix . 'dialbunny_phone_details';

     // Check if user used to own the number
     // Direct database query used below – $wpdb->prepare() is always used to prevent SQL injection.
     $opened_item = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}dialbunny_released_numbers WHERE phone = %s AND countrycode = %s LIMIT 1",$phone_number,$country_code)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery

     if ($opened_item->user == $user_id) {
       // Direct database query used below – $wpdb->prepare() is always used to prevent SQL injection.
       $opened_current = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}dialbunny_phone_details WHERE user = %d LIMIT 1", $user_id)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery

       // Backup current number into released table
       if (!empty($opened_current->managed_number) && !empty($opened_current->managed_number_code)) {
         $current_details = [
           'id' => uniqid(),
           'user' => $opened_current->user,
           'countrycode' => $opened_current->managed_number_code,
           'phone' => $opened_current->managed_number,
           'sid' => $opened_current->sid,
           'created_at' => current_time('mysql', 1),
           'updated_at' => current_time('mysql', 1)
         ];
         // Direct database query used below – Safely inserts data into the database using $wpdb->insert(), which handles proper escaping and prevents SQL injection.
         $wpdb->insert($released_table, $current_details); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
       }
       // Update with new number
       // Direct database query used below – Safely updates data into the database using $wpdb->update(), which handles proper escaping and prevents SQL injection.
       $wpdb->update($table, ['managed_number_code' => $country_code,'managed_number' => $phone_number,'sid' => $phone_sid,'updated_at' => current_time('mysql', 1)], ['user' => $user_id]); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
       // Remove new number from released table
       // Direct database query used below – Safely deletes data from the database using $wpdb->delete(), which handles proper escaping and prevents SQL injection.
       $wpdb->delete($released_table, ['phone' => $phone_number,'countrycode' => $country_code]); // phpcs:ignore WordPress.DB.DirectDatabaseQuery

       wp_safe_redirect(admin_url('admin.php?page=dialbunny_dashboard&phonenumberadded&user_nonce='.sanitize_text_field(wp_unslash($_POST['user_nonce']))));
     } else {
       wp_safe_redirect(admin_url('admin.php?page=dialbunny_dashboard&dashboardpage=released&erroraddingnumber&user_nonce='.sanitize_text_field(wp_unslash($_POST['user_nonce']))));
     }
     exit;
  }

  // Remove managed number from users account
  function release_managed_number()
  {
    if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { return; }

    global $wpdb;
    $user_id = get_current_user_id();

    // Sanitize input
    $countrycode = sanitize_text_field(wp_unslash($_POST['countrycode'] ?? ''));
    $phone = sanitize_text_field(wp_unslash($_POST['phone'] ?? ''));
    $phone_sid = sanitize_text_field(wp_unslash($_POST['phonesid'] ?? ''));

    $table = $wpdb->prefix . 'dialbunny_phone_details';

    // Update the user's managed number to mark it as released
    // Direct database query used below – Safely updates data into the database using $wpdb->update(), which handles proper escaping and prevents SQL injection.
    $updated = $wpdb->update($table, [ // phpcs:ignore WordPress.DB.DirectDatabaseQuery
      'managed_number_code' => '',
      'managed_number' => '', // reset the phone number
      'updated_at' => current_time('mysql', 1)
    ], [
      'managed_number' => $phone,
      'managed_number_code' => $countrycode,
      'user' => $user_id
    ]);

    if ($updated === false) {
      wp_safe_redirect(admin_url('admin.php?page=dialbunny_dashboard&phonenumberreleasederror&user_nonce='.sanitize_text_field(wp_unslash($_POST['user_nonce']))));
      exit;
    }

    // Move released number to the released table
    if (!empty($countrycode) && !empty($phone)) {
      $released_table = $wpdb->prefix . 'dialbunny_released_numbers';
      $current_details = [
        'id' => uniqid(),
        'user' => $user_id,
        'countrycode' => $countrycode,
        'phone' => $phone,
        'sid' => $phone_sid,
        'created_at' => current_time('mysql', 1),
        'updated_at' => current_time('mysql', 1)
      ];
      // Direct database query used below – Safely inserts data into the database using $wpdb->insert(), which handles proper escaping and prevents SQL injection.
      $wpdb->insert($released_table, $current_details); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    }

    wp_safe_redirect(admin_url('admin.php?page=dialbunny_dashboard&phonenumberreleased&user_nonce='.sanitize_text_field(wp_unslash($_POST['user_nonce']))));
    exit;
  }

  // Add new contact
  function new_contact()
  {
      if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { return; }

      global $wpdb;
      $blocked = isset($_POST['blocked']) ? 1 : 0;
      $user_id = get_current_user_id();
      $unique_id = uniqid();
      $table_name = $wpdb->prefix . 'dialbunny_contacts';

      // Sanitize inputs
      $name         = sanitize_text_field(wp_unslash($_POST['name'] ?? ''));
      $company      = sanitize_text_field(wp_unslash($_POST['company'] ?? ''));
      $countrycode  = sanitize_text_field(wp_unslash($_POST['countrycode'] ?? ''));
      $phone        = preg_replace('/[^0-9]/', '', sanitize_text_field(wp_unslash($_POST['phone'] ?? '')));
      $notes        = sanitize_textarea_field(wp_unslash($_POST['notes'] ?? ''));
      $icon         = sanitize_text_field(wp_unslash($_POST['icon'] ?? ''));

      // Insert contact
      // Direct database query used below – Safely inserts data into the database using $wpdb->insert(), which handles proper escaping and prevents SQL injection.
      $wpdb->insert($table_name, [ // phpcs:ignore WordPress.DB.DirectDatabaseQuery
        'id'          => $unique_id,
        'user'        => $user_id,
        'name'        => $name,
        'company'     => $company,
        'countrycode' => $countrycode,
        'phone'       => $phone,
        'notes'       => $notes,
        'icon'        => $icon,
        'blocked'     => $blocked,
        'created_at'  => current_time('mysql', 1),
        'updated_at'  => current_time('mysql', 1)
      ]);

      // Safe redirect
      $user_nonce = sanitize_text_field(wp_unslash($_POST['user_nonce']));
      $redirect_url = add_query_arg([
        'page'          => 'dialbunny_dashboard',
        'dashboardpage' => 'contacts',
        'contact'       => $unique_id,
        'user_nonce'    => $user_nonce, // carry it forward
      ], admin_url('admin.php'));

      wp_safe_redirect($redirect_url);
      exit;
  }

  // Update contact
  function update_contact()
  {
      if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { return; }
      global $wpdb;
      $user_id = get_current_user_id();
      $table   = $wpdb->prefix . 'dialbunny_contacts';

      // Sanitize input
      $id          = sanitize_text_field(wp_unslash($_POST['idValue'] ?? ''));
      $name        = sanitize_text_field(wp_unslash($_POST['name'] ?? ''));
      $company     = sanitize_text_field(wp_unslash($_POST['company'] ?? ''));
      $countrycode = sanitize_text_field(wp_unslash($_POST['countrycode'] ?? ''));
      $phone       = preg_replace('/[^0-9]/', '', sanitize_text_field(wp_unslash($_POST['phone'] ?? '')));
      $icon        = sanitize_text_field(wp_unslash($_POST['icon'] ?? ''));
      $status      = sanitize_text_field(wp_unslash($_POST['status'] ?? ''));
      $statuscolor = sanitize_text_field(wp_unslash($_POST['statuscolor'] ?? ''));
      $notes       = sanitize_textarea_field(wp_unslash($_POST['notes'] ?? ''));
      $blocked     = isset($_POST['blocked']) ? 1 : 0;

      // Update contact
      // Direct database query used below – Safely updates data into the database using $wpdb->update(), which handles proper escaping and prevents SQL injection.
      $wpdb->update($table, [ // phpcs:ignore WordPress.DB.DirectDatabaseQuery
        'name'        => $name,
        'blocked'     => $blocked,
        'countrycode' => $countrycode,
        'phone'       => $phone,
        'company'     => $company,
        'icon'        => $icon,
        'status'      => $status,
        'statuscolor' => $statuscolor,
        'notes'       => $notes,
        'updated_at'  => current_time('mysql', 1),
      ], [
        'id'   => $id,
        'user' => $user_id
      ]);

      // Safe redirect
      $user_nonce = sanitize_text_field(wp_unslash($_POST['user_nonce']));
      $redirect_url = add_query_arg([
        'page'          => 'dialbunny_dashboard',
        'dashboardpage' => 'contacts',
        'contact'       => $id,
        'user_nonce'    => $user_nonce, // carry it forward
      ], admin_url('admin.php'));

      wp_safe_redirect($redirect_url);
      exit;
  }

  // Remove contact
  function remove_contact()
  {
    if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { return; }

    global $wpdb;
    $user_id = get_current_user_id();
    $table   = $wpdb->prefix . 'dialbunny_contacts';

    // Sanitize input
    $id = sanitize_text_field(wp_unslash($_POST['idValue'] ?? ''));

    // Delete row
    // Direct database query used below – Safely deletes data from the database using $wpdb->delete(), which handles proper escaping and prevents SQL injection.
    $wpdb->delete($table, ['id'   => $id,'user' => $user_id]); // phpcs:ignore WordPress.DB.DirectDatabaseQuery

    // Safe redirect
    $user_nonce = sanitize_text_field(wp_unslash($_POST['user_nonce']));
    $redirect_url = add_query_arg([
      'page'          => 'dialbunny_dashboard',
      'dashboardpage' => 'contacts',
      'user_nonce'    => $user_nonce, // carry it forward
    ], admin_url('admin.php'));

    wp_safe_redirect($redirect_url);
    exit;
  }

  // Remove messages
  function remove_messages()
  {
    if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { return; }
    global $wpdb;
    $user_id = get_current_user_id();
    $table = $wpdb->prefix . 'dialbunny_messages';
    $details = $wpdb->prefix . 'dialbunny_phone_details';

    // Get the current user's managed number
    // Direct database query used below – $wpdb->prepare() is always used to prevent SQL injection.
    $phone_details = $wpdb->get_row($wpdb->prepare("SELECT managed_number FROM {$wpdb->prefix}dialbunny_phone_details WHERE user = %d LIMIT 1", $user_id)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery

    if (! $phone_details || empty($phone_details->managed_number)) {
      // Managed number not found
      wp_safe_redirect(admin_url('admin.php?page=dialbunny_dashboard&dashboardpage=messages&error=no_number&user_nonce='.sanitize_text_field(wp_unslash($_POST['user_nonce']))));
      exit;
    }
    // Sanitize input
    $target_phone = preg_replace('/[^0-9]/', '', sanitize_text_field(wp_unslash($_POST['phone'] ?? '')));
    // Delete message records (in both directions)
    // Direct database query used below – Safely deletes data from the database using $wpdb->delete(), which handles proper escaping and prevents SQL injection.
    $wpdb->delete($table, ['from_number' => $target_phone,'to_number'   => $phone_details->managed_number]); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    // Direct database query used below – Safely deletes data from the database using $wpdb->delete(), which handles proper escaping and prevents SQL injection.
    $wpdb->delete($table, ['to_number'   => $target_phone,'from_number' => $phone_details->managed_number]); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    // Safe redirect
    wp_safe_redirect(admin_url('admin.php?page=dialbunny_dashboard&dashboardpage=messages&user_nonce='.sanitize_text_field(wp_unslash($_POST['user_nonce']))));
    exit;
  }

  // Send a text message manually inside the dashboard
  function send_text()
  {
    if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { return; }
    global $wpdb;
    $user_id = get_current_user_id();
    $details_table = $wpdb->prefix . 'dialbunny_phone_details';

    // Get sender's managed number
    // Direct database query used below – $wpdb->prepare() is always used to prevent SQL injection.
    $phone_details = $wpdb->get_row($wpdb->prepare("SELECT managed_number_code, managed_number FROM {$wpdb->prefix}dialbunny_phone_details WHERE user = %d LIMIT 1",$user_id)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery

    if (! $phone_details || empty($phone_details->managed_number)) {
      wp_safe_redirect(admin_url('admin.php?page=dialbunny_dashboard&dashboardpage=messages&error=nosender&user_nonce='.sanitize_text_field(wp_unslash($_POST['user_nonce']))));
      exit;
    }

    // Sanitize inputs
    $to_country = preg_replace('/[^0-9]/', '', sanitize_text_field(wp_unslash($_POST['countrycode'] ?? '')));
    $to_number = preg_replace('/[^0-9]/', '', sanitize_text_field(wp_unslash($_POST['phoneNumber'] ?? '')));
    $message_body = sanitize_textarea_field(wp_unslash($_POST['textMessage'] ?? ''));

    // Combine phone number for Twilio
    $recipient = '+' . $to_country . $to_number;

    // Send message via Twilio
    try {
      $keys = new DialBunnyKeysClass();
      $client = new Client($keys->TWILIO_SID(), $keys->TWILIO_TOKEN());

      $client->messages->create($recipient, [
        "body" => $message_body,
        "from" => $phone_details->managed_number,
      ]);

      // Save message to database
      $table_name = $wpdb->prefix . 'dialbunny_messages';
      // Direct database query used below – Safely inserts data into the database using $wpdb->insert(), which handles proper escaping and prevents SQL injection.
      $wpdb->insert($table_name, [ // phpcs:ignore WordPress.DB.DirectDatabaseQuery
        'id' => uniqid() . 'you',
        'user' => $user_id,
        'from_countrycode' => $phone_details->managed_number_code,
        'from_number' => $phone_details->managed_number,
        'to_countrycode' => '+' . $to_country,
        'to_number' => $to_number,
        'message' => $message_body,
        'reading' => 1,
        'created_at' => current_time('mysql', 1)
      ]);

      // Redirect to conversation view
      $user_nonce = sanitize_text_field(wp_unslash($_POST['user_nonce']));
      $redirect_url = add_query_arg([
        'page' => 'dialbunny_dashboard',
        'dashboardpage' => 'messages',
        'phone' => $to_number,
        'countrycode' => '+' . $to_country,
        'user_nonce'    => $user_nonce, // carry it forward
      ], admin_url('admin.php'));

      wp_safe_redirect($redirect_url);
      exit;
    } catch (Exception $e) {
      wp_safe_redirect(admin_url('admin.php?page=dialbunny_dashboard&dashboardpage=messages&errorsending&user_nonce='.sanitize_text_field(wp_unslash($_POST['user_nonce']))));
      exit;
    }
  }

  // Start or join a video call request
  function get_video_call_token()
  {
    if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) 
    {
      if (sanitize_text_field(wp_unslash($_POST['user_nonce'])) != 'dialbunny_user_nonce') { return; exit; }
    }
    if (!isset($_POST['dialbunny_user'])) { return; exit; }
    if (!isset($_POST['videoroom'])) { return; exit; }
    $keys = new DialBunnyKeysClass();
    $accountSid = $keys->TWILIO_SID();
    $apiKeySid  = $keys->API_KEY();
    $apiKeySecret = $keys->API_SECRET();
    $token = new AccessToken(
        $accountSid,
        $apiKeySid,
        $apiKeySecret,
        3600,
        sanitize_text_field(wp_unslash($_POST['dialbunny_user']))
    );
    $videoGrant = new VideoGrant();
    $videoGrant->setRoom(sanitize_text_field(wp_unslash($_POST['videoroom'])));
    $token->addGrant($videoGrant);
    wp_send_json_success([
        'token' => $token->toJWT()
    ]);
  }

}
 ?>
