import * as plugins from '../plugins.js';
import * as paths from '../paths.js';
import { logger } from '../logger.js';

import type { ISmsConfig } from './config/sms.config.js';
import { smsConfigSchema } from './config/sms.schema.js';
import { ConfigValidator } from '../config/validator.js';

export class SmsService {
  public projectinfo!: plugins.projectinfo.ProjectInfo;
  public typedrouter = new plugins.typedrequest.TypedRouter();
  public config: ISmsConfig;

  constructor(options: ISmsConfig) {
    // Validate and apply defaults to configuration
    const validationResult = ConfigValidator.validate(options, smsConfigSchema);
    
    if (!validationResult.valid) {
      logger.warn(`SMS service configuration has validation errors: ${validationResult.errors!.join(', ')}`);
    }
    
    // Set configuration with defaults
    this.config = validationResult.config;
    
    // Add router to platform service
  }

  /**
   * starts the financeflow instance
   */
  public async start() {
    logger.log('info', `starting sms service`);
    this.projectinfo = await plugins.projectinfo.ProjectInfo.create(paths.packageDir);
    this.typedrouter.addTypedHandler(
      new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.platformservice.sms.IRequest_SendSms>(
        'sendSms',
        async (reqData) => {
          await this.sendSms(reqData.toNumber, reqData.fromName, reqData.messageText);
          return {
            status: 'ok',
          };
        }
      )
    );
    this.typedrouter.addTypedHandler(
      new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.platformservice.sms.IRequest_SendVerificationCode>(
        'sendVerificationCode',
        async (reqData) => {
          const verificationCode = (
            await this.sendVerificationCode(reqData.toNumber, reqData.fromName)
          ).toString();
          return {
            status: 'ok',
            verificationCode,
          };
        }
      )
    );
  }

  public async sendSms(toNumber: number, fromName: string, messageText: string) {
    // Use default sender if not specified
    const sender = fromName || this.config.defaultSender || 'PlatformService';
    
    const payload = {
      sender,
      message: messageText,
      recipients: [{ msisdn: toNumber }],
    };

    const resp = await plugins.smartrequest.SmartRequest.create()
      .url('https://gatewayapi.com/rest/mtsms')
      .header('Authorization', `Basic ${Buffer.from(`${this.config.apiGatewayApiToken}:`).toString('base64')}`)
      .header('Content-Type', 'application/json')
      .json(payload)
      .post();
    const json = await resp.json();
    logger.log('info', `sent an sms to ${toNumber} with text '${messageText}'`, {
      eventType: 'sentSms',
      sms: {
        fromName: fromName,
        toNumber: toNumber.toString(),
        messageText: messageText,
      },
    });
    console.log(JSON.stringify(json, null, 2));
  }

  public async sendVerificationCode(toNumber: number, fromName: string) {
    let verificationCode = Math.floor(100000 + Math.random() * 900000);
    await this.sendSms(toNumber, fromName, `Your verification code: ${verificationCode}`);
    return verificationCode;
  }

  public async stop() {}
}
