import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import axios from 'axios';

@Injectable()
export class SmsService {
  constructor(private configService: ConfigService) {}

  async sendSms(
    phoneNumber: string,
    message: string,
    options: {
      senderId?: string;
      callbackUrl?: string;
    } = {},
  ): Promise<any> {
    try {
      const response = await axios.post(
        'https://api.safaricom.co.ke/sms/v1/send',
        {
          recipients: [phoneNumber],
          message,
          senderId: options.senderId || this.configService.get('SMS_SENDER_ID'),
          callbackUrl: options.callbackUrl || this.configService.get('SMS_CALLBACK_URL'),
        },
        {
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${await this.getAccessToken()}`,
          },
        }
      );

      return response.data;
    } catch (error) {
      throw new Error(`Failed to send SMS: ${error.message}`);
    }
  }

  async sendOrderUpdateNotification(
    phoneNumber: string,
    orderId: string,
    status: string,
  ): Promise<void> {
    const message = `Your order ${orderId} has been updated to ${status}. Visit our website for more details.`;
    await this.sendSms(phoneNumber, message);
  }

  async sendPaymentConfirmation(
    phoneNumber: string,
    orderId: string,
    amount: number,
  ): Promise<void> {
    const message = `Payment of KES ${amount} for order ${orderId} has been successfully processed.`;
    await this.sendSms(phoneNumber, message);
  }

  async sendMaintenanceAlert(
    phoneNumber: string,
    machineId: string,
    issue: string,
  ): Promise<void> {
    const message = `Maintenance alert: Machine ${machineId} requires attention. Issue: ${issue}.`;
    await this.sendSms(phoneNumber, message);
  }

  async sendReminder(
    phoneNumber: string,
    message: string,
  ): Promise<void> {
    await this.sendSms(phoneNumber, message);
  }

  private async getAccessToken(): Promise<string> {
    const { CONSUMER_KEY, CONSUMER_SECRET } = this.configService.get('sms');

    const response = await axios.get(
      'https://api.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials',
      {
        auth: {
          username: CONSUMER_KEY,
          password: CONSUMER_SECRET,
        },
      }
    );

    // Type guard for access_token
    if (response.data && typeof response.data === 'object' && 'access_token' in response.data) {
      return (response.data as { access_token: string }).access_token;
    }
    throw new Error('Failed to retrieve access token from SMS response');
  }
}
