package auth

import (
	"strings"

	"gitlab.com/dynaweb/ains-microservices/pkg/delima"
)

const (
	RoleMurid   = "murid"
	RoleTeacher = "teacher"
	RolePPD     = "ppd"
	RoleJPN     = "jpn"
	RoleKPM     = "kpm"
)

var roleMap = map[string]string{
	"g":    RoleTeacher,
	"m":    RoleMurid,
	"jpn":  RoleJPN,
	"ppd":  RolePPD,
	"bstp": RoleKPM,
}

var allowedRoles = map[string]bool{
	RoleMurid:   true,
	RoleTeacher: true,
	RolePPD:     true,
	RoleJPN:     true,
	RoleKPM:     true,
}

var stateMap = map[string]string{
	"WP KUALA LUMPUR": "WILAYAH PERSEKUTUAN KUALA LUMPUR",
	"WP PUTRAJAYA":    "WILAYAH PERSEKUTUAN PUTRAJAYA",
	"WP LABUAN":       "WILAYAH PERSEKUTUAN LABUAN",
}

type User struct {
	ID         int64
	Username   string
	Fullname   string
	Email      string
	ImgURL     string
	Provider   string
	Role       string
	State      string
	PPD        string
	School     string
	ClassYear  string
	ClassName  string
	LoginToken string
}

type School struct {
	ID       int64
	Code     string
	Name     string
	Email    string
	Address  string
	City     string
	Postcode string
	PPD      string
	State    string
	Type     string
}

func EmailType(email string) string {
	local := email
	if at := strings.Index(local, "@"); at >= 0 {
		local = local[:at]
	}
	if dash := strings.Index(local, "-"); dash >= 0 {
		local = local[:dash]
	}
	return strings.ToLower(local)
}

func RoleFromEmailType(emailType string) (string, bool) {
	role, ok := roleMap[emailType]
	return role, ok
}

func ResolveRole(email string, duser *delima.User) string {
	emailType := EmailType(email)

	if duser != nil && duser.Role.Text != "" {
		switch duser.Role.Text {
		case "student":
			return RoleMurid
		case "other-users", "admin":
			if role, ok := roleMap[emailType]; ok {
				return role
			}
			return ""
		default:
			if role, ok := roleMap[emailType]; ok {
				return role
			}
			return ""
		}
	}

	if role, ok := roleMap[emailType]; ok {
		return role
	}
	return ""
}

func AllowedRole(role string) bool {
	return allowedRoles[role]
}

func NormalizeState(state string) string {
	if mapped, ok := stateMap[strings.ToUpper(strings.TrimSpace(state))]; ok {
		return mapped
	}
	return state
}
