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

/**
 * VMO Twilio REST API Manager
 * 
 * Lightweight Twilio integration using WordPress HTTP API
 * NO COMPOSER SDK REQUIRED - Works on any WordPress host
 * 
 * @package VMO_AI_Website_Builder
 * @since 1.0.0
 */

if ( ! defined('ABSPATH') ) exit;

class VMO_Twilio_REST {
    private $sid;
    private $token;
    private $base;

    public function __construct( $sid = '', $token = '' ) {
        $this->sid = $sid ?: (
            defined('VMO_TWILIO_ACCOUNT_SID')
                ? VMO_TWILIO_ACCOUNT_SID
                : get_option('vmo_twilio_account_sid', get_option('vmo_twilio_sid', ''))
        );
        $this->token = $token ?: (
            defined('VMO_TWILIO_AUTH_TOKEN')
                ? VMO_TWILIO_AUTH_TOKEN
                : get_option('vmo_twilio_auth_token', get_option('vmo_twilio_token', ''))
        );
        $this->base  = 'https://api.twilio.com/2010-04-01';
    }

    /**
     * Generate Authorization header for Twilio API
     */
    private function auth_header_value() {
        return 'Basic ' . base64_encode($this->sid . ':' . $this->token); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- HTTP Basic auth header
    }

    private function request_headers($include_content_type = false) {
        $headers = array(
            'Authorization' => $this->auth_header_value(),
        );

        if ($include_content_type) {
            $headers['Content-Type'] = 'application/x-www-form-urlencoded';
        }

        return $headers;
    }

    private function has_credentials() {
        return !empty($this->sid) && !empty($this->token);
    }

    /**
     * POST request to Twilio API
     */
    private function post($path, $body) {
        if (!$this->has_credentials()) {
            return new WP_Error('twilio_missing', 'Twilio credentials not configured.');
        }

        $url = trailingslashit($this->base) . ltrim($path, '/');
        $res = wp_remote_post($url, [
            'headers' => $this->request_headers(true),
            'body'    => $body,
            'timeout' => 30,
        ]);
        
        if ( is_wp_error($res) ) return $res;
        
        $code = wp_remote_retrieve_response_code($res);
        $json = json_decode(wp_remote_retrieve_body($res), true);
        
        return $code >= 200 && $code < 300 
            ? $json 
            : new WP_Error('twilio_rest_error', 'Twilio REST error', ['code'=>$code,'body'=>$json]);
    }

    /**
     * GET request to Twilio API
     */
    private function get($path, $query = []) {
        if (!$this->has_credentials()) {
            return new WP_Error('twilio_missing', 'Twilio credentials not configured.');
        }

        $url = trailingslashit($this->base) . ltrim($path, '/');
        if ($query) $url = add_query_arg($query, $url);
        
        $res = wp_remote_get($url, [
            'headers' => $this->request_headers(),
            'timeout' => 30,
        ]);
        
        if ( is_wp_error($res) ) return $res;
        
        $code = wp_remote_retrieve_response_code($res);
        $json = json_decode(wp_remote_retrieve_body($res), true);
        
        return $code >= 200 && $code < 300 
            ? $json 
            : new WP_Error('twilio_rest_error', 'Twilio REST error', ['code'=>$code,'body'=>$json]);
    }

    /**
     * DELETE request to Twilio API
     */
    private function delete($path) {
        if (!$this->has_credentials()) {
            return new WP_Error('twilio_missing', 'Twilio credentials not configured.');
        }

        $url = trailingslashit($this->base) . ltrim($path, '/');
        
        $res = wp_remote_request($url, [
            'method'  => 'DELETE',
            'headers' => $this->request_headers(),
            'timeout' => 30,
        ]);
        
        if ( is_wp_error($res) ) return $res;
        
        $code = wp_remote_retrieve_response_code($res);
        // 204 No Content is success for DELETE
        return $code >= 200 && $code < 300 
            ? true 
            : new WP_Error('twilio_rest_error', 'Twilio REST error', ['code'=>$code]);
    }

    /**
     * Create a subaccount for a user
     * 
     * @param string $friendlyName Descriptive name for the subaccount
     * @return array|WP_Error Subaccount data or error
     */
    public function create_subaccount($friendlyName) {
        return $this->post("Accounts.json", [
            'FriendlyName' => sanitize_text_field($friendlyName),
        ]);
    }

    /**
     * Provision a phone number
     * 
     * @param string $accountSid The account SID to provision for
     * @param string $areaCodeOrPattern Area code or pattern to search for
     * @param string $isoCountry ISO country code (default: US)
     * @param bool $smsEnabled Enable SMS (default: true)
     * @param bool $voiceEnabled Enable voice (default: true)
     * @return array|WP_Error Phone number data or error
     */
    public function provision_number($accountSid, $areaCodeOrPattern = '', $isoCountry = 'US', $smsEnabled=true, $voiceEnabled=true) {
        // Search available numbers
        $search = $this->get("Accounts/{$accountSid}/AvailablePhoneNumbers/{$isoCountry}/Local.json", [
            'Contains' => sanitize_text_field($areaCodeOrPattern),
            'SmsEnabled' => $smsEnabled ? 'true':'false',
            'VoiceEnabled' => $voiceEnabled ? 'true':'false',
        ]);
        
        if ( is_wp_error($search) ) return $search;
        
        if ( empty($search['available_phone_numbers'][0]['phone_number']) )
            return new WP_Error('no_numbers', 'No available numbers found');

        $phone = $search['available_phone_numbers'][0]['phone_number'];

        // Purchase number
        return $this->post("Accounts/{$accountSid}/IncomingPhoneNumbers.json", [
            'PhoneNumber' => $phone
        ]);
    }

    /**
     * Send SMS message
     * 
     * @param string $to Recipient phone number
     * @param string $from Sender phone number
     * @param string $body Message body
     * @return array|WP_Error Message data or error
     */
    public function send_sms($to, $from, $body) {
        return $this->post("Accounts/{$this->sid}/Messages.json", [
            'To' => sanitize_text_field($to),
            'From' => sanitize_text_field($from),
            'Body' => sanitize_textarea_field($body),
        ]);
    }

    /**
     * Make phone call
     * 
     * @param string $to Recipient phone number
     * @param string $from Caller phone number
     * @param string $url TwiML URL for call instructions
     * @return array|WP_Error Call data or error
     */
    public function make_call($to, $from, $url) {
        return $this->post("Accounts/{$this->sid}/Calls.json", [
            'To' => sanitize_text_field($to),
            'From' => sanitize_text_field($from),
            'Url' => esc_url_raw($url),
        ]);
    }

    /**
     * List phone numbers on account
     * 
     * @return array|WP_Error Phone numbers or error
     */
    public function list_numbers() {
        return $this->get("Accounts/{$this->sid}/IncomingPhoneNumbers.json");
    }

    /**
     * Release (Delete) a phone number
     * 
     * @param string $incomingPhoneNumberSid The SID of the phone number to release
     * @return bool|WP_Error True on success, error on failure
     */
    public function release_number($incomingPhoneNumberSid) {
        return $this->delete("Accounts/{$this->sid}/IncomingPhoneNumbers/{$incomingPhoneNumberSid}.json");
    }

    /**
     * Test connection to Twilio
     * 
     * @return array|WP_Error Account data or error
     */
    public function test_connection() {
        return $this->get("Accounts/{$this->sid}.json");
    }
}
