import axios from 'axios';
import { Message } from 'eris';
import type { Stripe } from 'stripe';
import { Client, Command } from '../class';
import type { PromoInterface } from '../models';

export default class Billing_T3 extends Command {
  constructor(client: Client) {
    super(client);
    this.name = 't3';
    this.description = 'Subscription to CS Tier 3.';
    this.usage = `${this.client.config.prefix}billing t3 [promoCode]`;
    this.permissions = 0;
    this.guildOnly = false;
    this.enabled = true;
  }

  public async run(message: Message, args: string[]) {
    try {
      await message.delete();
      const response = <{
        found: boolean,
        emailAddress?: string,
        tier?: number,
        supportKey?: string,
      }>(await axios.get(`https://api.cloud.libraryofcode.org/wh/info?id=${message.author.id}&authorization=${this.client.config.internalKey}`)).data;
      if (!response.found) return this.error(message.channel, 'CS Account not found.');

      const customer = await this.client.db.Customer.findOne({ userID: message.author.id });
      if (!customer) return this.error(message.channel, `You do not have a Customer Account. Please run \`${this.client.config.prefix}billing\`, once you visit the Billing Portal via the URL given to you, please try again.`);

      let promoCode: PromoInterface;
      if (args[0]) {
        promoCode = await this.client.db.Promo.findOne({ code: args[0].toUpperCase() });
      }

      let subscription: Stripe.Response<Stripe.Subscription>;
      try {
        subscription = await this.client.stripe.subscriptions.create({
          customer: customer.cusID,
          payment_behavior: 'allow_incomplete',
          items: [{ price: 'price_1H8e6ODatwI1hQ4WFVvX6Nda' }],
          days_until_due: 1,
          collection_method: 'send_invoice',
          default_tax_rates: ['txr_1HlAadDatwI1hQ4WRHu14S2I'],
          promotion_code: promoCode ? promoCode.id : undefined,
        });
      } catch (err) {
        return this.error(message.channel, `Error creating subscription.\n\n${err}`);
      }

      await this.client.stripe.invoices.finalizeInvoice(subscription.latest_invoice.toString());
      const invoice = await this.client.stripe.invoices.retrieve(subscription.latest_invoice.toString());

      const chan = await this.client.getDMChannel(message.author.id);
      await chan.createMessage(`__**Invoice for New Subscription**__\n${invoice.hosted_invoice_url}\n\n*Please click on the link above to pay for your subscription.*`);
      return this.success(message.channel, 'Transaction processed.');
    } catch (err) {
      return this.client.util.handleError(err, message, this);
    }
  }
}
