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

use Twilio\Rest\Client;

class DialBunnyAdminController {

  function add_managed_number() {
    if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { echo 'Permission Denied!'; return; }
    if ( !current_user_can('administrator') ) { echo 'Permission Denied!'; return; }
    if (!isset($_POST['user']) && !isset($_POST['countrycode']) && !isset($_POST['phone'])) { echo 'Permission Denied!'; return; }

    global $wpdb;
    $username = sanitize_user(wp_unslash($_POST['user']));
    // Direct database query used below – $wpdb->prepare() is always used to prevent SQL injection.
    $user = $wpdb->get_var($wpdb->prepare("SELECT ID FROM {$wpdb->users} WHERE user_login = %s LIMIT 1", $username)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    if (!$user) { $user = $username; }
    if (empty($_POST['countrycode']) || empty($_POST['phone']) || empty($_POST['phonenumbersid'])) { wp_safe_redirect(admin_url('admin.php?page=dialbunny_add&error1')); exit; }
    $code = sanitize_text_field(wp_unslash($_POST['countrycode'])); if (! preg_match('/^\+?[0-9]{1,15}$/', $code)) { wp_safe_redirect(admin_url('admin.php?page=dialbunny_add&error1')); exit; }
    $phone = sanitize_text_field(wp_unslash($_POST['phone'])); if (! preg_match('/^[0-9]{4,15}$/', $phone)) { wp_safe_redirect(admin_url('admin.php?page=dialbunny_add&error1')); exit; }
    $sid = sanitize_text_field(wp_unslash($_POST['phonenumbersid']));
    $table = $wpdb->prefix . 'dialbunny_phone_details';
    $add_success;

    // Check to see if the phone number is used by another WordPress user
    // Direct database query used below – $wpdb->prepare() is always used to prevent SQL injection.
    $existing = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->prefix}dialbunny_phone_details WHERE managed_number_code = %s AND managed_number = %s AND user != %d",$code,$phone,$user)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    if ($existing > 0) {
        // Number is already used by someone else
        wp_safe_redirect(admin_url('admin.php?page=dialbunny_add&error2'));
        exit;
    }
    // Direct database query used below – $wpdb->prepare() is always used to prevent SQL injection.
    $opened_item = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}dialbunny_phone_details WHERE user = %d LIMIT 1", $user)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery

    $now = current_time('mysql', 1); // UTC time

    if (empty($opened_item)) {
      $data = array(
        'id' => uniqid(),
        'user' => $user,
        'managed_number_code' => $code,
        'managed_number' => $phone,
        'sid' => $sid,
        'status' => 'active',
        'created_at' => $now,
        'updated_at' => $now
      );
      // Direct database query used below – Safely inserts data into the database using $wpdb->insert(), which handles proper escaping and prevents SQL injection.
      $add_success = $wpdb->insert($table, $data); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    } else {
      $data = array(
        'managed_number_code' => $code,
        'managed_number' => $phone,
        'sid' => $sid,
        'updated_at' => $now
      );
      // Direct database query used below – Safely updates data into the database using $wpdb->update(), which handles proper escaping and prevents SQL injection.
      $add_success = $wpdb->update($table, $data, array('user' => $user)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    }

    if ($add_success) { wp_safe_redirect(admin_url('admin.php?page=dialbunny_add&success')); } else { wp_safe_redirect(admin_url('admin.php?page=dialbunny_add&error1')); }
  }

  function remove_managed_number() {
    if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { echo 'Permission Denied!'; return; }
    if ( !current_user_can('administrator') ) { echo 'Permission Denied!'; return; }
    if (!isset($_POST['countrycode']) && !isset($_POST['phone'])) { echo 'Permission Denied!'; return; }

    global $wpdb;
    $code = sanitize_text_field(wp_unslash($_POST['countrycode'])); if (! preg_match('/^\+?[0-9]{1,15}$/', $code)) { echo esc_url(wp_safe_redirect(admin_url('admin.php?page=dialbunny_remove&error1'))); exit; }
    $phone = sanitize_text_field(wp_unslash($_POST['phone'])); if (! preg_match('/^[0-9]{4,15}$/', $phone)) { echo esc_url(wp_safe_redirect(admin_url('admin.php?page=dialbunny_remove&error1'))); exit; }

    $table = $wpdb->prefix . 'dialbunny_phone_details';
    $released_table = $wpdb->prefix . 'dialbunny_released_numbers';
    // 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,array('managed_number_code' => '', 'managed_number' => ''),array('managed_number_code' => $code, 'managed_number' => $phone),array('%s', '%s'),array('%s', '%s')); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    $deleted = $wpdb->delete($released_table, ['phone' => $phone,'countrycode' => $code]); // phpcs:ignore WordPress.DB.DirectDatabaseQuery

    if ($updated || $deleted) { wp_safe_redirect(admin_url('admin.php?page=dialbunny_remove&success')); } else { wp_safe_redirect(admin_url('admin.php?page=dialbunny_remove&error1')); }
    exit;
  }

  function additional_setup() {
    if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { echo 'Permission Denied!'; return; }
    if ( !current_user_can('administrator') ) { echo 'Permission Denied!'; return; }
    if (!isset($_POST['dialbunny_user_can_request_number']) || !isset($_POST['dialbunny_user_guest_video_page'])) { echo 'Permission Denied!'; return; }

    $value = sanitize_text_field(wp_unslash($_POST['dialbunny_user_can_request_number'])); if ( $value !== 'true' && $value !== 'false' ) { echo esc_html('Error updating settings. Invalid form request.'); exit; }
    $videoPage = sanitize_text_field(wp_unslash($_POST['dialbunny_user_guest_video_page'])); 
    update_option('dialbunny_user_can_request_number', $value === 'true');
    update_option('dialbunny_user_guest_video_page', $videoPage);

    wp_safe_redirect(admin_url('admin.php?page=dialbunny_setup&tabpage=additional&success1'));
    exit;
  }

  function update_license_key()
  {
    if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { echo 'Permission Denied!'; return; }
    if ( !current_user_can('administrator') ) { echo 'Permission Denied!'; return; }
    if ( !isset($_POST['license_key']) ) { echo 'Permission Denied!'; return; }
    global $wpdb;
    $table = $wpdb->prefix . 'dialbunny_api_keys';
    $licenseKey = sanitize_text_field(wp_unslash($_POST['license_key']));
    // Direct database query used below – $wpdb->prepare() is always used to prevent SQL injection.
    $existing = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}dialbunny_api_keys WHERE id = %s LIMIT 1", 'ACWJB59' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    $data = ['updated_at' => $now];
    if (!$existing) {
      $data['id'] = 'ACWJB59';
      $data['created_at'] = $now;
      $data['license_key'] = $licenseKey;
      // 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 {
      $data['license_key'] = $licenseKey;
      // 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, array('id' => 'ACWJB59')); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    }
    wp_safe_redirect(admin_url('admin.php?page=dialbunny_license'));
    exit;
  }

  function setup_api_keys() {
    if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { echo 'You do not have permission to submit that request.'; return; }
    if ( !current_user_can('administrator') ) { echo 'You do not have permission to submit that request.'; echo 'Permission Denied!'; return; }

    global $wpdb;
    $encrypt = new DialBunnyKeysClass();
    $table = $wpdb->prefix . 'dialbunny_api_keys';
    // Direct database query used below – $wpdb->prepare() is always used to prevent SQL injection.
    $existing = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}dialbunny_api_keys WHERE id = %s LIMIT 1", 'ACWJB59' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    $now = current_time('mysql', 1); // UTC time
    $fields = ['TWILIO_SID', 'TWILIO_TOKEN', 'TwiML_App_SID', 'API_KEY', 'API_SECRET'];
    $data = array();
    
    if (empty($_POST['TWILIO_SID']) || empty($_POST['TWILIO_TOKEN'])) { wp_safe_redirect(admin_url('admin.php?page=dialbunny_setup&warning1')); exit; }
    if (empty($existing)) {
      $data['twilio_sid'] = $encrypt->encrypt_data(sanitize_text_field(wp_unslash($_POST['TWILIO_SID'])));
      $data['twilio_token'] = $encrypt->encrypt_data(sanitize_text_field(wp_unslash($_POST['TWILIO_TOKEN'])));
      $data['id'] = 'ACWJB59';
      $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
      wp_safe_redirect(admin_url('admin.php?page=dialbunny_setup&success1')); exit;
    } else {
      foreach ($fields as $field) {
      if (!empty($_POST['TWILIO_SID']) && !empty($_POST['TWILIO_TOKEN']) && isset($_POST[$field]) && $encrypt->{$field}() != sanitize_text_field(wp_unslash($_POST[$field]))) {
        $data['updated_at'] = $now;
        $data[$field] = $encrypt->encrypt_data(sanitize_text_field(wp_unslash($_POST[$field])));
        }
      }
      // Direct database query used below – Safely updates data into the database using $wpdb->update(), which handles proper escaping and prevents SQL injection.
      if ($data != null) { $wpdb->update($table, $data, array('id' => 'ACWJB59')); $wpdb->delete($table, array('id' => 'ACWJB59auto'), array('%s')); wp_safe_redirect(admin_url('admin.php?page=dialbunny_setup&success1')); exit; } // phpcs:ignore WordPress.DB.DirectDatabaseQuery 
      else { wp_safe_redirect(admin_url('admin.php?page=dialbunny_setup&warning1')); exit; }
    }
  }

  function auto_setup_api_keys()
  {
    if ( !isset($_POST['user_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['user_nonce'])), 'DialBunny') ) { echo 'Permission Denied!'; return; }
    if ( !current_user_can('administrator') ) { echo 'Permission Denied!'; return; }
    global $wpdb;
    $dialbunny_keys_backup_info = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}dialbunny_api_keys WHERE id = %s LIMIT 1", 'ACWJB59backup')); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    $dialbunny_active_sids = $wpdb->get_results("SELECT sid FROM {$wpdb->prefix}dialbunny_phone_details Where managed_number_code != '' AND managed_number != '' LIMIT 100"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    $dialbunny_released_sids = $wpdb->get_results("SELECT sid FROM {$wpdb->prefix}dialbunny_released_numbers LIMIT 100"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    $dialbunny_phone_sids = array_merge($dialbunny_active_sids, $dialbunny_released_sids);
    $dialbunny_keys = new DialBunnyKeysClass();
    $dialbunny_sid = $dialbunny_keys->TWILIO_SID();
    $dialbunny_token = $dialbunny_keys->TWILIO_TOKEN();
    if ($dialbunny_keys->TWILIO_SID() != '' && $dialbunny_keys->TWILIO_TOKEN() != '')
    {
      try 
      {
        $dialbunny_client = new Client($dialbunny_sid, $dialbunny_token);
        $encrypt = new DialBunnyKeysClass();
        // 1. Create a TwiML App
        $twimlApp = $dialbunny_client->applications->create([
            "friendlyName" => "dialbunny_twimlApp_".get_bloginfo('name'),
            // Change this to your webhook URL
            "voiceUrl"      => admin_url('admin-post.php?action=dialbunny_calls_logic'),
            "voiceMethod"   => "POST",
            "smsUrl"        => admin_url('admin-post.php?action=dialbunny_incoming_texts'),
            "smsMethod"     => "POST",
        ]);
        // 2. Create a Twilio API Key + Secret
        $apiKey = $dialbunny_client->newKeys->create([
            "friendlyName" => "dialbunny_apiKeys_".get_bloginfo('name'),
        ]);
        if (!empty($dialbunny_keys_backup_info[0]->id))
        {
          try { $dialbunny_client->applications($encrypt->decrypt_data($dialbunny_keys_backup_info[0]->TwiML_App_SID))->delete(); $dialbunny_client->keys($encrypt->decrypt_data($dialbunny_keys_backup_info[0]->API_KEY))->delete(); } catch (Exception $e) {}
        }
        if ($apiKey && $twimlApp)
        {
          // Update all phone numbers to new Twiml App
          foreach ($dialbunny_phone_sids as $dialbunny_record)
          {
            try { if ($dialbunny_record->sid != null) {
            $dialbunny_client->incomingPhoneNumbers($dialbunny_record->sid)->update([
              'emergencyStatus' => 'Inactive',
              'voiceApplicationSid' => $twimlApp->sid,
              'smsApplicationSid'   => $twimlApp->sid,
              'smsMethod' => 'POST',
              'voiceMethod' => 'POST',
            ]); } } catch (Exception $e) {}
          }
          $table = $wpdb->prefix . 'dialbunny_api_keys';
          $now = current_time('mysql', 1); // UTC time
          $data = array(
            'TwiML_App_SID' => $encrypt->encrypt_data($twimlApp->sid),
            'API_KEY' => $encrypt->encrypt_data($apiKey->sid),
            'API_SECRET' => $encrypt->encrypt_data($apiKey->secret),
            'created_at' => $now,
            'updated_at' => $now
          );
          $data2 = array(
            'id' => 'ACWJB59auto',
            'TwiML_App_SID' => 'dialbunny_twimlApp_'.get_bloginfo('name'),
            'API_KEY' => 'dialbunny_apiKeys_'.get_bloginfo('name'),
            'API_SECRET' => 'dialbunny_apiKeys_'.get_bloginfo('name'),
            'created_at' => $now,
            'updated_at' => $now
          );
          $data3 = array(
            'id' => 'ACWJB59backup',
            'TwiML_App_SID' => $encrypt->encrypt_data($twimlApp->sid),
            'API_KEY' => $encrypt->encrypt_data($apiKey->sid),
            'API_SECRET' => $encrypt->encrypt_data($apiKey->secret),
            'created_at' => $now,
            'updated_at' => $now
          );
          $wpdb->update($table, $data, array('id' => 'ACWJB59')); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
          $wpdb->replace($table, $data2); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
          $wpdb->replace($table, $data3); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
          wp_safe_redirect(admin_url('admin.php?page=dialbunny_setup&success2'));
          exit;
        }
        else { wp_safe_redirect(admin_url('admin.php?page=dialbunny_setup&error=Error&errorcode=400')); exit; }
      }
      catch (Exception $e) 
      {  
        wp_safe_redirect(admin_url('admin.php?page=dialbunny_setup&error='.$e->getMessage().'&errorcode='.$e->getCode()));
        exit;
      }
    }
  }
}
?>
