<?php
/**
 * Acc_SMS — ارسال پیامک (کاوه‌نگار، ملی‌پیامک، قاصدک، لاگ دمو)
 */
if ( ! defined( 'ABSPATH' ) ) exit;

class Acc_SMS {

    public static function config(): array {
        return [
            'provider'    => (string) get_option( 'acc_sms_provider', 'log' ),
            'api_key'     => (string) get_option( 'acc_sms_api_key', '' ),
            'sender'      => (string) get_option( 'acc_sms_sender', '' ),
            'otp_template'=> (string) get_option( 'acc_sms_otp_template', 'verify' ),
        ];
    }

    public static function send( string $phone, string $message ): array {
        $phone = self::_normalize( $phone );
        if ( ! $phone ) {
            return [ 'success' => false, 'message' => 'شماره موبایل نامعتبر' ];
        }

        $hook = apply_filters( 'acc_send_sms', null, $phone, $message );
        if ( $hook === true ) {
            return [ 'success' => true, 'provider' => 'filter' ];
        }
        if ( is_array( $hook ) && isset( $hook['success'] ) ) {
            return $hook;
        }

        $cfg = self::config();
        $provider = $cfg['provider'] ?: 'log';

        $result = match ( $provider ) {
            'kavenegar'   => self::_kavenegar( $phone, $message, $cfg ),
            'melipayamak' => self::_melipayamak( $phone, $message, $cfg ),
            'ghasedak'    => self::_ghasedak( $phone, $message, $cfg ),
            default       => self::_log_only( $phone, $message ),
        };

        self::_write_log( $phone, $message, $result );
        return $result;
    }

    public static function send_otp( string $phone, string $code ): array {
        $cfg = self::config();
        $phone = self::_normalize( $phone );

        if ( $cfg['provider'] === 'kavenegar' && $cfg['api_key'] && $cfg['otp_template'] ) {
            $res = self::_kavenegar_lookup( $phone, $code, $cfg );
            if ( $res['success'] ) {
                return $res;
            }
        }

        $msg = "کد تأیید سامانه هوادران: {$code}\nاعتبار: ۵ دقیقه";
        return self::send( $phone, $msg );
    }

    private static function _normalize( string $phone ): string {
        $phone = preg_replace( '/\D/', '', $phone );
        if ( str_starts_with( $phone, '98' ) && strlen( $phone ) === 12 ) {
            $phone = '0' . substr( $phone, 2 );
        }
        return preg_match( '/^09\d{9}$/', $phone ) ? $phone : '';
    }

    private static function _log_only( string $phone, string $message ): array {
        return [
            'success'  => true,
            'provider' => 'log',
            'message'  => 'پیامک در حالت دمو/لاگ ثبت شد (provider=log)',
        ];
    }

    private static function _kavenegar_lookup( string $phone, string $code, array $cfg ): array {
        $api  = $cfg['api_key'];
        $tpl  = $cfg['otp_template'];
        $receptor = self::_intl( $phone );
        $url  = "https://api.kavenegar.com/v1/{$api}/verify/lookup.json";
        $body = http_build_query( [
            'receptor' => $receptor,
            'token'    => $code,
            'template' => $tpl,
        ] );
        $res = self::_http_post( $url, $body, 'application/x-www-form-urlencoded' );
        if ( ! empty( $res['return']['status'] ) && (int) $res['return']['status'] === 200 ) {
            return [ 'success' => true, 'provider' => 'kavenegar' ];
        }
        $err = $res['return']['message'] ?? ( $res['message'] ?? 'خطای کاوه‌نگار' );
        return [ 'success' => false, 'message' => $err, 'provider' => 'kavenegar' ];
    }

    private static function _kavenegar( string $phone, string $message, array $cfg ): array {
        if ( empty( $cfg['api_key'] ) ) {
            return [ 'success' => false, 'message' => 'API Key کاوه‌نگار تنظیم نشده' ];
        }
        $sender = $cfg['sender'] ?: '10004346';
        $url    = "https://api.kavenegar.com/v1/{$cfg['api_key']}/sms/send.json";
        $body   = http_build_query( [
            'sender'  => $sender,
            'receptor'=> self::_intl( $phone ),
            'message' => $message,
        ] );
        $res = self::_http_post( $url, $body, 'application/x-www-form-urlencoded' );
        if ( ! empty( $res['return']['status'] ) && (int) $res['return']['status'] === 200 ) {
            return [ 'success' => true, 'provider' => 'kavenegar' ];
        }
        return [ 'success' => false, 'message' => $res['return']['message'] ?? 'خطای ارسال', 'provider' => 'kavenegar' ];
    }

    private static function _melipayamak( string $phone, string $message, array $cfg ): array {
        if ( empty( $cfg['api_key'] ) ) {
            return [ 'success' => false, 'message' => 'API Key ملی‌پیامک تنظیم نشده' ];
        }
        $url  = 'https://console.melipayamak.com/api/send/simple/' . rawurlencode( $cfg['api_key'] );
        $res  = self::_http_post( $url, wp_json_encode( [
            'from' => $cfg['sender'] ?: '5000...',
            'to'   => self::_intl( $phone ),
            'text' => $message,
        ] ) );
        if ( ! empty( $res['recId'] ) || ( isset( $res['status'] ) && $res['status'] === 'ارسال شد' ) ) {
            return [ 'success' => true, 'provider' => 'melipayamak' ];
        }
        return [ 'success' => false, 'message' => $res['status'] ?? 'خطای ملی‌پیامک', 'provider' => 'melipayamak' ];
    }

    private static function _ghasedak( string $phone, string $message, array $cfg ): array {
        if ( empty( $cfg['api_key'] ) ) {
            return [ 'success' => false, 'message' => 'API Key قاصدک تنظیم نشده' ];
        }
        $res = self::_http_post(
            'https://api.ghasedak.me/v2/sms/send/simple',
            wp_json_encode( [
                'message'     => $message,
                'receptor'    => self::_intl( $phone ),
                'linenumber'  => $cfg['sender'] ?: '',
            ] ),
            'application/json',
            [ 'apikey: ' . $cfg['api_key'] ]
        );
        if ( ! empty( $res['result']['code'] ) && (int) $res['result']['code'] === 200 ) {
            return [ 'success' => true, 'provider' => 'ghasedak' ];
        }
        return [ 'success' => false, 'message' => $res['message'] ?? 'خطای قاصدک', 'provider' => 'ghasedak' ];
    }

    private static function _intl( string $phone ): string {
        if ( str_starts_with( $phone, '0' ) ) {
            return '98' . substr( $phone, 1 );
        }
        return $phone;
    }

    private static function _http_post( string $url, string $body, string $content_type = 'application/json', array $extra_headers = [] ): array {
        $headers = array_merge( [ 'Content-Type: ' . $content_type ], $extra_headers );
        if ( function_exists( 'wp_remote_post' ) ) {
            $resp = wp_remote_post( $url, [
                'headers' => array_reduce( $headers, function ( $carry, $h ) {
                    $p = explode( ':', $h, 2 );
                    if ( count( $p ) === 2 ) {
                        $carry[ trim( $p[0] ) ] = trim( $p[1] );
                    }
                    return $carry;
                }, [] ),
                'body'    => $body,
                'timeout' => 20,
            ] );
            if ( is_wp_error( $resp ) ) {
                return [ 'message' => $resp->get_error_message() ];
            }
            return json_decode( wp_remote_retrieve_body( $resp ), true ) ?: [];
        }
        $ch = curl_init( $url );
        curl_setopt_array( $ch, [
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => $body,
            CURLOPT_HTTPHEADER     => $headers,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT        => 20,
        ] );
        $raw = curl_exec( $ch );
        curl_close( $ch );
        return json_decode( (string) $raw, true ) ?: [];
    }

    private static function _write_log( string $phone, string $message, array $result ): void {
        $dir = ( defined( 'ACC_PATH' ) ? ACC_PATH : dirname( __DIR__, 2 ) . '/' ) . 'logs';
        if ( ! is_dir( $dir ) ) {
            @mkdir( $dir, 0755, true );
        }
        $line = date( 'Y-m-d H:i:s' ) . " [{$phone}] " . ( $result['provider'] ?? '?' ) . ' '
            . ( $result['success'] ? 'OK' : 'FAIL' ) . " — {$message}\n";
        @file_put_contents( $dir . '/acc-sms.log', $line, FILE_APPEND );
    }
}
