package postgresql

import (
	"context"

	"github.com/jackc/pgx/v5"

	"log"

	"github.com/stripe/stripe-go/v83"

	"alfheimgame.com/alfheim/pkg/models"
)

type SubscriptionModel struct {
	DB *pgx.Conn
}

func (m *SubscriptionModel) Insert(stripeid string, stripesubscriptionid string, stripecheckoutid string, status stripe.SubscriptionStatus) (int32, error) {
	var id int32
	stmt := `SELECT id FROM accounts WHERE stripe_id = $1`

	err := m.DB.QueryRow(context.Background(), stmt, stripeid).Scan(&id)
	if err != nil {
		log.Println(err)
		return 0, err
	}

	stmt = `INSERT INTO subscriptions (account_id, stripe_subscription_id, stripe_checkout_id, status) VALUES ($1, $2, $3, $4::subscription_status) RETURNING id`

	var insertid int32

	err = m.DB.QueryRow(context.Background(), stmt, id, string(stripesubscriptionid), string(stripecheckoutid), string(status)).Scan(&insertid)
	if err != nil {
		log.Println(err)
		return 0, err
	}

	return insertid, nil
}

func (m *SubscriptionModel) Delete(id int32) error {
	stmt := `DELETE FROM accounts WHERE id = $1`

	_, err := m.DB.Exec(context.Background(), stmt, id)
	if err != nil {
		log.Println(err)
		return err
	}

	return nil
}

func (m *SubscriptionModel) GetSubscription(id int32) (models.Subscription, error) {
	if id == 0 {
		return models.Subscription{}, models.ErrNoRecord
	}

	var subscription models.Subscription
	stmt := `SELECT id, account_id, stripe_subscription_id, stripe_checkout_id, status FROM subscriptions WHERE id = $1`
	err := m.DB.QueryRow(context.Background(), stmt, id).Scan(&subscription.ID, &subscription.AccountID, &subscription.StripeSubscriptionID, &subscription.StripeCheckoutID, &subscription.Status)

	if err == pgx.ErrNoRows {
		return models.Subscription{}, pgx.ErrNoRows
	} else if err != nil {
		return models.Subscription{}, err
	}

	return subscription, nil
}

func (m *SubscriptionModel) GetSubscriptionsFromAccount(accountid int32) ([]models.Subscription, error) {
	if accountid == 0 {
		return nil, models.ErrNoRecord
	}

	stmt := `SELECT id, account_id, stripe_subscription_id, stripe_checkout_id, status FROM subscriptions WHERE account_id = $1`
	rows, err := m.DB.Query(context.Background(), stmt, accountid)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var subscriptions []models.Subscription
	for rows.Next() {
		var subscription models.Subscription
		err := rows.Scan(&subscription.ID, &subscription.AccountID, &subscription.StripeSubscriptionID, &subscription.StripeCheckoutID, &subscription.Status)
		if err == pgx.ErrNoRows {
			return nil, pgx.ErrNoRows
		} else if err != nil {
			return nil, err
		}

		subscriptions = append(subscriptions, subscription)
	}

	return subscriptions, nil
}

func (m *SubscriptionModel) HasActiveSubscription(accountid int32) bool {
	subscriptions, err := m.GetSubscriptionsFromAccount(accountid)
	if err != nil {
		return false
	}

	for _, v := range subscriptions {
		switch v.Status {
		case models.Active:
			return true
		case models.Trialing:
			return true
		}
	}

	return false
}
