package models

import (
	"time"

	"errors"
	"strconv"

	"code.justin.tv/common/yimg"
)

type FilterParams struct {
	IDs          []string
	Logins       []string
	Emails       []string
	DisplayNames []string
	Ips          []string
}

type PropertiesResult struct {
	Results []*Properties `json:"results"`
}

type Properties struct {
	ID                      string       `json:"id" `
	Login                   *string      `json:"login" `
	Birthday                *time.Time   `json:"birthday" `
	DmcaViolation           *bool        `json:"dmca_violation" `
	TermsOfServiceViolation *bool        `json:"terms_of_service_violation" `
	DeletedOn               *time.Time   `json:"deleted_on" `
	Language                *string      `json:"language" `
	Category                *string      `json:"category" `
	RemoteIP                *string      `json:"remote_ip" `
	Email                   *string      `json:"email" `
	LastLogin               *string      `json:"last_login" `
	BannedUntil             *time.Time   `json:"banned_until" `
	DmcaViolationCount      *int         `json:"dmca_violation_count" `
	TosViolationCount       *int         `json:"tos_violation_count" `
	Admin                   *bool        `json:"admin" `
	Subadmin                *bool        `json:"subadmin" `
	GlobalMod               *bool        `json:"global_mod" `
	Displayname             *string      `json:"displayname" `
	Description             *string      `json:"description" `
	ProfileImage            *yimg.Images `json:"profile_image" `
	UpdatedOn               *time.Time   `json:"updated_on" `
	CreatedOn               *time.Time   `json:"created_on" `
	EmailVerified           *bool        `json:"email_verified" `
	PhoneNumber             *string      `json:"phone_number" `
	LastLoginChangeDate     *time.Time   `json:"last_login_change_date" `
}

func (p Properties) ConvertToIntIDProperties() (IntIDProperties, error) {
	i, err := strconv.ParseUint(p.ID, 10, 64)
	if err != nil {
		return IntIDProperties{}, errors.New("Unable to return string user id as int")
	}
	return IntIDProperties{
		ID:                      i,
		Login:                   p.Login,
		Birthday:                p.Birthday,
		DmcaViolation:           p.DmcaViolation,
		TermsOfServiceViolation: p.TermsOfServiceViolation,
		DeletedOn:               p.DeletedOn,
		Language:                p.Language,
		Category:                p.Category,
		RemoteIP:                p.RemoteIP,
		Email:                   p.Email,
		LastLogin:               p.LastLogin,
		BannedUntil:             p.BannedUntil,
		DmcaViolationCount:      p.DmcaViolationCount,
		TosViolationCount:       p.TosViolationCount,
		Admin:                   p.Admin,
		Subadmin:                p.Subadmin,
		GlobalMod:               p.GlobalMod,
		Displayname:             p.Displayname,
		Description:             p.Description,
		ProfileImage:            p.ProfileImage,
		UpdatedOn:               p.UpdatedOn,
		CreatedOn:               p.CreatedOn,
		EmailVerified:           p.EmailVerified,
		PhoneNumber:             p.PhoneNumber,
		LastLoginChangeDate:     p.LastLoginChangeDate,
	}, nil
}

type IntIDProperties struct {
	ID                      uint64       `json:"id" `
	Login                   *string      `json:"login" `
	Birthday                *time.Time   `json:"birthday" `
	DmcaViolation           *bool        `json:"dmca_violation" `
	TermsOfServiceViolation *bool        `json:"terms_of_service_violation" `
	DeletedOn               *time.Time   `json:"deleted_on" `
	Language                *string      `json:"language" `
	Category                *string      `json:"category" `
	RemoteIP                *string      `json:"remote_ip" `
	Email                   *string      `json:"email" `
	LastLogin               *string      `json:"last_login" `
	BannedUntil             *time.Time   `json:"banned_until" `
	DmcaViolationCount      *int         `json:"dmca_violation_count" `
	TosViolationCount       *int         `json:"tos_violation_count" `
	Admin                   *bool        `json:"admin" `
	Subadmin                *bool        `json:"subadmin" `
	GlobalMod               *bool        `json:"global_mod" `
	Displayname             *string      `json:"displayname" `
	Description             *string      `json:"description" `
	ProfileImage            *yimg.Images `json:"profile_image" `
	UpdatedOn               *time.Time   `json:"updated_on" `
	CreatedOn               *time.Time   `json:"created_on" `
	EmailVerified           *bool        `json:"email_verified" `
	PhoneNumber             *string      `json:"phone_number" `
	LastLoginChangeDate     *time.Time   `json:"last_login_change_date" `
}

type RenameProperties struct {
	RenameEligible   *bool      `json:"rename_eligible"`
	RenameEligibleOn *time.Time `json:"rename_eligible_on"`
}

type UpdateableProperties struct {
	ID                string     `json:"-" `
	Login             *string    `json:"-" `
	Birthday          *time.Time `json:"birthday" `
	Email             *string    `json:"email" `
	Displayname       *string    `json:"displayname" `
	Language          *string    `json:"language" `
	Description       *string    `json:"description"`
	EmailVerified     *bool      `json:"email_verified"`
	NewLogin          *string    `json:"new_login"`
	SkipLoginCooldown *bool      `json:"skip_login_cooldown"`

	ReleaseDateDuration time.Duration `json:"-"`
}

func (u *UpdateableProperties) FillFromProperties(p *Properties) {
	u.ID = p.ID
	u.Login = p.Login

	if u.Email == nil {
		u.Email = p.Email
	}
	if u.Displayname == nil {
		u.Displayname = p.Displayname
	}
	if u.Language == nil {
		u.Language = p.Language
	}
	if u.Description == nil {
		u.Description = p.Description
	}
	if u.EmailVerified == nil {
		u.EmailVerified = p.EmailVerified
	}
}
