package mysql

import (
	"context"
	"fmt"

	"gorm.io/gorm"

	"github.com/pingcap-inc/data-ingestion-tools/model"
)

type createdRevrec struct {
	db *gorm.DB
}

func newCreatedRevrec(ds *datastore) *createdRevrec {
	return &createdRevrec{db: ds.db}
}

func (c *createdRevrec) List(_ context.Context) (records []model.CreatedRevrec, err error) {
	err = c.db.Find(&records).Error
	return
}

func (c *createdRevrec) ListCurrentMonth(_ context.Context, billMonth string) (records []*model.CreatedRevrec, err error) {
	err = c.db.Where("bill_month = ?", billMonth).Find(&records).Error
	return
}

func (c *createdRevrec) Update(_ context.Context, record *model.CreatedRevrec) error {
	return c.db.Save(record).Error
}

func (c *createdRevrec) DeleteAndSave(_ context.Context, records []model.CreatedRevrec) ([]model.CreatedRevrec, error) {
	if len(records) == 0 {
		return nil, nil
	}
	// clear the records of the current month
	c.db.Where("bill_month = ? and sync = ?", records[0].BillMonth, 0).Unscoped().Delete(&model.CreatedRevrec{})

	dRecords := make([]model.CreatedRevrec, 0)
	for _, record := range records {
		var tmpRevrec model.CreatedRevrec
		err := c.db.Where("bill_month = ? and original_tenant_id = ? and type = ?", record.BillMonth, record.OriginalTenantID, record.Type).First(&tmpRevrec).Error
		if err == gorm.ErrRecordNotFound {
			err = c.db.Create(&record).Error
			if err != nil {
				return nil, err
			}

			dRecords = append(dRecords, record)
		}
	}

	return dRecords, nil
}

func (c *createdRevrec) GetByOrderID(_ context.Context, orderID string) (record model.CreatedRevrec, err error) {
	err = c.db.Where("order", orderID).First(&record).Error
	return
}

func (c *createdRevrec) UpdateRevrecs(records []model.CreatedRevrec) error {
	if len(records) == 0 {
		return nil
	}
	for _, record := range records {
		updates := map[string]interface{}{
			"new_order_serverless_amount": record.NewOrderServerlessAmount,
			"new_order_dedicated_amount":  record.NewOrderDedicatedAmount,
			"new_order_support_amount":    record.NewOrderSupportAmount,
		}
		err := c.db.Model(&model.CreatedRevrec{}).
			Where("bill_month = ? AND account_number = ? AND adjust_tenant_id = ?",
				record.BillMonth, record.AccountNumber, record.AdjustTenantID).
			Updates(updates).Error
		if err != nil {
			return fmt.Errorf("failed to update record for account %s: %w", record.AccountNumber, err)
		}
	}

	return nil
}
