package psql

import (
	"database/sql"
	"errors"
	"kurumibot/database"
	"log"
	"math"
	"time"

	"github.com/shopspring/decimal"
	"gorm.io/gorm"
)

type User struct {
	ID         int
	TelegramID int `gorm:"column:tg_id"`
	Balance    decimal.Decimal
	Name       string
	GroupID    int `gorm:"default:1"`
	Group      *Group
	Level      int `gorm:"default:1"`
	Exp        int `gorm:"default:0"`
	WorkID     int `gorm:"default:1"`
	Work       *Work
	WorkTime   time.Time

	AutoID     sql.NullInt64
	Auto       *ShopAuto
	BusinessID sql.NullInt64
	Business   *ShopBusiness
	MaidID     sql.NullInt64
	Maid       *ShopMaid
	MinerID    sql.NullInt64
	Miner      *ShopMiner

	IncomeTime time.Time
	BTC        decimal.Decimal
	Invested   decimal.Decimal
	PairID     sql.NullInt64
	Pair       *User
	Greeting   string `gorm:"size:255,default:Привет"`
	Donat      int    `gorm:"default:0"`
	FractionID sql.NullInt64
	Fraction   *Fraction

	MoneyIncome decimal.Decimal
	ExpIncome   int
	BtcIncome   decimal.Decimal

	WaifuSearchTime time.Time
}

func GetOrCreateUser(tgId int, name string) (*User, error) {
	user, err := GetUser(tgId)
	log.Println(errors.Is(err, gorm.ErrRecordNotFound))
	if errors.Is(err, gorm.ErrRecordNotFound) {
		_, err = CreateUser(tgId, name)
		if err != nil {
			return nil, err
		}
		return GetUser(tgId)
	}
	return user, err
}

func CreateUser(tgId int, name string) (*User, error) {
	user := &User{
		TelegramID: tgId,
		Name:       name,
	}
	tx := database.PostgresDatabase.Create(user)
	return user, tx.Error
}

func GetUser(telegramId int) (*User, error) {
	user := new(User)
	tx := database.PostgresDatabase.Joins("Group").Joins("Work").Joins("Auto").Joins("Business").Joins("Maid").Joins("Miner").Joins("Fraction").Preload("Pair").Take(user, "tg_id=?", telegramId)
	return user, tx.Error
}

func GetAllUsers() ([]*User, error) {
	users := make([]*User, 0)
	tx := database.PostgresDatabase.Joins("Group").Joins("Work").Joins("Auto").Joins("Business").Joins("Maid").Joins("Miner").Joins("Fraction").Preload("Pair").Find(&users)
	return users, tx.Error
}

func CountLevel(userXp int) (int, int) {
	xp := 0
	nextLevel := 2
	for {
		xp = int(math.Pow(float64(nextLevel), 3)) * (nextLevel * 3)
		if xp > userXp {
			break
		}
		if nextLevel == 200 {
			break
		}
		nextLevel++
	}
	return nextLevel - 1, xp
}
