<?php

namespace App\Services;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;

class SmsService
{
    protected $provider;

    protected $apiKey;

    protected $shortcode;

    protected $senderId;

    protected $enabled;

    protected $oauthClientId;

    protected $oauthClientSecret;

    protected $oauthUsername;

    protected $oauthPassword;

    protected $channelId;

    protected $oauthAccessToken;

    protected $oauthRefreshToken;

    protected $oauthTokenExpires;

    public function __construct()
    {
        $this->provider = DB::table('settings')->where('key', 'sms_provider')->value('value') ?? 'nenasasa';
        $this->apiKey = DB::table('settings')->where('key', 'sms_api_key')->value('value');
        $this->shortcode = DB::table('settings')->where('key', 'sms_shortcode')->value('value');
        $this->senderId = DB::table('settings')->where('key', 'sms_sender_id')->value('value');
        $this->enabled = DB::table('settings')->where('key', 'sms_enabled')->value('value') === '1';

        $this->oauthClientId = DB::table('settings')->where('key', 'sms_oauth_client_id')->value('value');
        $this->oauthClientSecret = DB::table('settings')->where('key', 'sms_oauth_client_secret')->value('value');
        $this->oauthUsername = DB::table('settings')->where('key', 'sms_oauth_username')->value('value');
        $this->oauthPassword = DB::table('settings')->where('key', 'sms_oauth_password')->value('value');
        $this->channelId = DB::table('settings')->where('key', 'sms_channel_id')->value('value');
        $this->oauthAccessToken = DB::table('settings')->where('key', 'sms_oauth_access_token')->value('value');
        $this->oauthRefreshToken = DB::table('settings')->where('key', 'sms_oauth_refresh_token')->value('value');
        $this->oauthTokenExpires = DB::table('settings')->where('key', 'sms_oauth_token_expires')->value('value');
    }

    public function isEnabled()
    {
        return $this->enabled && ! empty($this->oauthClientId) && ! empty($this->oauthUsername) && ! empty($this->oauthPassword);
    }

    public function send($phoneNumber, $message)
    {
        if (! $this->isEnabled()) {
            return [
                'success' => false,
                'message' => 'SMS is not configured or not enabled.',
            ];
        }

        $phone = $this->formatPhoneNumber($phoneNumber);

        return $this->sendViaNenasasa($phone, $message);
    }

    protected function formatPhoneNumber($phone)
    {
        $phone = preg_replace('/[^0-9]/', '', $phone);

        if (substr($phone, 0, 1) === '0') {
            $phone = '254'.substr($phone, 1);
        } elseif (substr($phone, 0, 3) !== '254') {
            $phone = '254'.$phone;
        }

        return $phone;
    }

    protected function getNenasasaToken()
    {
        if (! empty($this->oauthAccessToken) && ! empty($this->oauthTokenExpires) && strtotime($this->oauthTokenExpires) > time()) {
            return $this->oauthAccessToken;
        }

        try {
            // Token endpoint: https://nenasasa.com/api/v1/o/token/
            $response = Http::withHeaders([
                'Content-Type' => 'application/json',
                'Accept' => 'application/json',
            ])->timeout(30)->post('https://nenasasa.com/api/v1/o/token/', [
                'client_id' => $this->oauthClientId,
                'username' => $this->oauthUsername,
                'password' => $this->oauthPassword,
                'grant_type' => 'password',
            ]);

            if ($response->successful()) {
                $data = $response->json();

                if (isset($data['access_token'])) {
                    $expiresAt = now()->addSeconds($data['expires_in'] ?? 36000);

                    DB::table('settings')->updateOrInsert(
                        ['key' => 'sms_oauth_access_token'],
                        ['value' => $data['access_token'], 'updated_at' => now()]
                    );
                    DB::table('settings')->updateOrInsert(
                        ['key' => 'sms_oauth_refresh_token'],
                        ['value' => $data['refresh_token'] ?? '', 'updated_at' => now()]
                    );
                    DB::table('settings')->updateOrInsert(
                        ['key' => 'sms_oauth_token_expires'],
                        ['value' => $expiresAt->toDateTimeString(), 'updated_at' => now()]
                    );

                    return $data['access_token'];
                }
            }

            DB::table('settings')->updateOrInsert(
                ['key' => 'sms_last_error'],
                ['value' => 'Token failed: '.$response->body(), 'updated_at' => now()]
            );

            return null;
        } catch (\Exception $e) {
            DB::table('settings')->updateOrInsert(
                ['key' => 'sms_last_error'],
                ['value' => 'Token exception: '.$e->getMessage(), 'updated_at' => now()]
            );

            return null;
        }
    }

    protected function sendViaNenasasa($phone, $message)
    {
        try {
            $token = $this->getNenasasaToken();

            if (! $token) {
                return [
                    'success' => false,
                    'message' => 'Failed to obtain OAuth token from nenasasa.com',
                ];
            }

            // SMS endpoint: https://nenasasa.com/api/v1/SEND SMS
            $response = Http::withHeaders([
                'Authorization' => 'Bearer '.$token,
                'Content-Type' => 'application/json',
                'Accept' => 'application/json',
            ])->timeout(30)->post('https://nenasasa.com/api/v1/SEND SMS', [
                'chid' => $this->channelId,
                'message' => $message,
                'alias' => $this->senderId ?: 'POSAI',
                'msisdn' => $phone,
            ]);

            $data = $response->json();

            if ($response->successful() || (isset($data['response_status']) && $data['response_status'] === '00')) {
                return [
                    'success' => true,
                    'message' => 'SMS sent successfully via nenasasa.com',
                ];
            }

            return [
                'success' => false,
                'message' => $data['last_response'] ?? 'Failed to send SMS via nenasasa.com',
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Error: '.$e->getMessage(),
            ];
        }
    }

    public function getSettings()
    {
        return [
            'provider' => $this->provider,
            'api_key' => $this->apiKey,
            'shortcode' => $this->shortcode,
            'sender_id' => $this->senderId,
            'enabled' => $this->enabled,
            'oauth_client_id' => $this->oauthClientId,
            'oauth_client_secret' => $this->oauthClientSecret,
            'oauth_username' => $this->oauthUsername,
            'oauth_password' => $this->oauthPassword,
            'channel_id' => $this->channelId,
            'last_error' => DB::table('settings')->where('key', 'sms_last_error')->value('value') ?? '',
        ];
    }

    public function testSms($phone)
    {
        return $this->send($phone, 'This is a test message from PosAI. If you received this, your SMS integration is working correctly!');
    }
}
