package reaper

import (
	"time"

	"github.com/google/uuid"
	"gorm.io/gorm"
)

type Language struct {
	ID   uuid.UUID
	Code string `gorm:"primaryKey;index:,unique"`
	ISO  *string
}

func (b *Language) BeforeCreate(tx *gorm.DB) (err error) {
	if b.ID == uuid.Nil {
		b.ID = uuid.New()
	}
	return
}

type Genre struct {
	ID     uuid.UUID
	RawTag string `gorm:"index:,unique"`
	Tag    *string
	Name   *string
}

func (b *Genre) BeforeCreate(tx *gorm.DB) (err error) {
	if b.ID == uuid.Nil {
		b.ID = uuid.New()
	}
	return
}

type Author struct {
	ID         uuid.UUID `gorm:"primaryKey;index:,unique;autoIncrement:true"`
	Key        string    `gorm:",unique"`
	FirstName  string
	MiddleName *string
	LastName   *string
	IsBanned   *bool
	BanReason  *string
	Books      []Book `gorm:"many2many:BookAuthor"`
}

func (b *Author) BeforeCreate(tx *gorm.DB) (err error) {
	if b.ID == uuid.Nil {
		b.ID = uuid.New()
	}
	return
}

type User struct {
	ID       uuid.UUID `gorm:"primaryKey"`
	Username string    `gorm:"autoIncrement:false;index:,unique"`
	Avatar   *string
	Name     *string
	Admin    bool
	Lang     *string
	Language *Language `gorm:"foreignKey:Lang"`
	LastSeen time.Time
	Created  time.Time
	Password string
	OTPToken *string
	//Favorites   []Book `gorm:"many2many:FavoriteBook;ForeignKey:username"`
	BookShelf []ReaderBook
}

func (b *User) BeforeCreate(tx *gorm.DB) (err error) {
	if b.ID == uuid.Nil {
		b.ID = uuid.New()
	}
	return
}

type Translator struct {
	ID         uuid.UUID `gorm:"primaryKey;index:,unique"`
	Key        string    `gorm:",unique"`
	FirstName  string
	MiddleName *string
	LastName   *string
}

func (b *Translator) BeforeCreate(tx *gorm.DB) (err error) {
	if b.ID == uuid.Nil {
		b.ID = uuid.New()
	}
	return
}

type Sequence struct {
	ID   uuid.UUID `gorm:",unique"`
	Name string    `gorm:"primaryKey;index:,unique"`
}

func (b *Sequence) BeforeCreate(tx *gorm.DB) (err error) {
	if b.ID == uuid.Nil {
		b.ID = uuid.New()
	}
	return
}

type Publisher struct {
	ID   uuid.UUID `gorm:",unique;autoIncrement:true"`
	Name string    `gorm:"primaryKey;index:,unique"`
}

func (b *Publisher) BeforeCreate(tx *gorm.DB) (err error) {
	if b.ID == uuid.Nil {
		b.ID = uuid.New()
	}
	return
}

type Book struct {
	ID           uuid.UUID `gorm:"primaryKey"`
	Title        string
	Authors      []Author `gorm:"many2many:BookAuthor;References:ID"`
	Lang         *string
	Language     Language `gorm:"foreignKey:Lang"`
	Genre        *[]Genre `gorm:"many2many:BookGenre;References:RawTag"`
	Description  *string  `gorm:"type:text"`
	HasCover     bool
	IsTranslated bool
	Translators  *[]Translator `gorm:"many2many:BookTranslator;References:ID"`
	SrcLang      *string
	SrcLanguage  Language `gorm:"foreignKey:SrcLang"`
	Sequence     *string
	SequenceID   *Sequence `gorm:"foreignKey:Sequence"`
	SequenceBook *int
	Year         *int
	Publisher    *string
	PublisherID  *Publisher `gorm:"foreignKey:Publisher"`
	Isbn         *string
	Downloads    int `gorm:"default:0"`
	Views        int `gorm:"default:0"`
	SymbolsCount *int
	PagesCount   *int // pdf
	Size         int
	Hash         *string
	Bookcase     *string
	Filename     string
	// FiletypeID    uint
	Filetype      string
	UploadedByID  *uint
	UploadedBy    *User
	UploadedAt    *time.Time
	Collections   []Collection `gorm:"many2many:CollectionBook;"`
	ExternalCover *string
}

func (b *Book) BeforeCreate(tx *gorm.DB) (err error) {
	if b.ID == uuid.Nil {
		b.ID = uuid.New()
	}
	return
}

//	type Filetype struct {
//		ID       uint   `gorm:"primaryKey"`
//		Filetype string `gorm:"uniqueIndex"`
//		Name     string
//	}
type ReaderBook struct {
	ID       uuid.UUID `gorm:"primaryKey"`
	UserID   uuid.UUID
	BookID   uuid.UUID
	Book     Book `gorm:"foreignKey:BookID"`
	Progress float64
	LastRead time.Time
}

func (b *ReaderBook) BeforeCreate(tx *gorm.DB) (err error) {
	if b.ID == uuid.Nil {
		b.ID = uuid.New()
	}
	return
}

type Collection struct {
	ID       uuid.UUID `gorm:"primaryKey"`
	Link     string    `gorm:"uniqueIndex"`
	Name     string
	UserID   uuid.UUID
	Creator  User   `gorm:"foreignKey:UserID"`
	Books    []Book `gorm:"many2many:CollectionBook;"`
	Created  time.Time
	Modified time.Time
}

func (b *Collection) BeforeCreate(tx *gorm.DB) (err error) {
	if b.ID == uuid.Nil {
		b.ID = uuid.New()
	}
	return
}
