package application

import (
	"context"
	"fmt"
	"strconv"
	"strings"

	"git.defalsify.org/vise.git/db"
	"git.defalsify.org/vise.git/lang"
	"git.defalsify.org/vise.git/resource"
	"git.grassecon.net/grassrootseconomics/common/person"
	storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
)

// SaveFirstname updates the first name in the gdbm with the provided input.
func (h *MenuHandlers) SaveFirstname(ctx context.Context, sym string, input []byte) (resource.Result, error) {
	var res resource.Result
	var err error
	sessionId, ok := ctx.Value("SessionId").(string)
	if !ok {
		return res, fmt.Errorf("missing session")
	}
	firstName := string(input)

	store := h.userdataStore
	logdb := h.logDb

	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
	flag_firstname_set, _ := h.flagManager.GetFlag("flag_firstname_set")

	allowUpdate := h.st.MatchFlag(flag_allow_update, true)
	firstNameSet := h.st.MatchFlag(flag_firstname_set, true)
	if allowUpdate {
		temporaryFirstName, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
		if len(temporaryFirstName) == 0 {
			logg.ErrorCtxf(ctx, "temporaryFirstName is empty", "key", storedb.DATA_TEMPORARY_VALUE)
			return res, fmt.Errorf("Data error encountered")
		}
		err = store.WriteEntry(ctx, sessionId, storedb.DATA_FIRST_NAME, []byte(temporaryFirstName))
		if err != nil {
			logg.ErrorCtxf(ctx, "failed to write firstName entry with", "key", storedb.DATA_FIRST_NAME, "value", temporaryFirstName, "error", err)
			return res, err
		}
		res.FlagSet = append(res.FlagSet, flag_firstname_set)

		err = logdb.WriteLogEntry(ctx, sessionId, storedb.DATA_FIRST_NAME, []byte(temporaryFirstName))
		if err != nil {
			logg.DebugCtxf(ctx, "Failed to write firtname db log entry", "key", storedb.DATA_FIRST_NAME, "value", temporaryFirstName)
		}
	} else {
		if firstNameSet {
			err = store.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(firstName))
			if err != nil {
				logg.ErrorCtxf(ctx, "failed to write temporaryFirstName entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", firstName, "error", err)
				return res, err
			}
		} else {
			h.profile.InsertOrShift(0, firstName)
		}
	}

	return res, nil
}

// SaveFamilyname updates the family name in the gdbm with the provided input.
func (h *MenuHandlers) SaveFamilyname(ctx context.Context, sym string, input []byte) (resource.Result, error) {
	var res resource.Result
	var err error
	sessionId, ok := ctx.Value("SessionId").(string)
	if !ok {
		return res, fmt.Errorf("missing session")
	}

	store := h.userdataStore
	logdb := h.logDb
	familyName := string(input)

	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
	flag_familyname_set, _ := h.flagManager.GetFlag("flag_familyname_set")
	allowUpdate := h.st.MatchFlag(flag_allow_update, true)
	familyNameSet := h.st.MatchFlag(flag_familyname_set, true)

	if allowUpdate {
		temporaryFamilyName, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
		if len(temporaryFamilyName) == 0 {
			logg.ErrorCtxf(ctx, "temporaryFamilyName is empty", "key", storedb.DATA_TEMPORARY_VALUE)
			return res, fmt.Errorf("Data error encountered")
		}
		err = store.WriteEntry(ctx, sessionId, storedb.DATA_FAMILY_NAME, []byte(temporaryFamilyName))
		if err != nil {
			logg.ErrorCtxf(ctx, "failed to write familyName entry with", "key", storedb.DATA_FAMILY_NAME, "value", temporaryFamilyName, "error", err)
			return res, err
		}
		res.FlagSet = append(res.FlagSet, flag_familyname_set)

		err = logdb.WriteLogEntry(ctx, sessionId, storedb.DATA_FAMILY_NAME, []byte(temporaryFamilyName))
		if err != nil {
			logg.DebugCtxf(ctx, "Failed to write firtname db log entry", "key", storedb.DATA_FAMILY_NAME, "value", temporaryFamilyName)
		}
	} else {
		if familyNameSet {
			err = store.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(familyName))
			if err != nil {
				logg.ErrorCtxf(ctx, "failed to write temporaryFamilyName entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", familyName, "error", err)
				return res, err
			}
		} else {
			h.profile.InsertOrShift(1, familyName)
		}
	}

	return res, nil
}

// VerifyYob verifies the length of the given input.
func (h *MenuHandlers) VerifyYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
	var res resource.Result
	var err error

	flag_incorrect_date_format, _ := h.flagManager.GetFlag("flag_incorrect_date_format")
	date := string(input)
	_, err = strconv.Atoi(date)
	if err != nil {
		// If conversion fails, input is not numeric
		res.FlagSet = append(res.FlagSet, flag_incorrect_date_format)
		return res, nil
	}

	if person.IsValidYOb(date) {
		res.FlagReset = append(res.FlagReset, flag_incorrect_date_format)
	} else {
		res.FlagSet = append(res.FlagSet, flag_incorrect_date_format)
	}
	return res, nil
}

// ResetIncorrectYob resets the incorrect date format flag after a new attempt.
func (h *MenuHandlers) ResetIncorrectYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
	var res resource.Result

	flag_incorrect_date_format, _ := h.flagManager.GetFlag("flag_incorrect_date_format")
	res.FlagReset = append(res.FlagReset, flag_incorrect_date_format)
	return res, nil
}

// SaveYOB updates the Year of Birth(YOB) in the gdbm with the provided input.
func (h *MenuHandlers) SaveYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
	var res resource.Result
	var err error
	sessionId, ok := ctx.Value("SessionId").(string)
	if !ok {
		return res, fmt.Errorf("missing session")
	}
	yob := string(input)
	store := h.userdataStore
	logdb := h.logDb

	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
	flag_yob_set, _ := h.flagManager.GetFlag("flag_yob_set")

	allowUpdate := h.st.MatchFlag(flag_allow_update, true)
	yobSet := h.st.MatchFlag(flag_yob_set, true)

	if allowUpdate {
		temporaryYob, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
		if len(temporaryYob) == 0 {
			logg.ErrorCtxf(ctx, "temporaryYob is empty", "key", storedb.DATA_TEMPORARY_VALUE)
			return res, fmt.Errorf("Data error encountered")
		}
		err = store.WriteEntry(ctx, sessionId, storedb.DATA_YOB, []byte(temporaryYob))
		if err != nil {
			logg.ErrorCtxf(ctx, "failed to write yob entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", temporaryYob, "error", err)
			return res, err
		}
		res.FlagSet = append(res.FlagSet, flag_yob_set)

		err = logdb.WriteLogEntry(ctx, sessionId, storedb.DATA_YOB, []byte(temporaryYob))
		if err != nil {
			logg.DebugCtxf(ctx, "Failed to write yob db log entry", "key", storedb.DATA_YOB, "value", temporaryYob)
		}
	} else {
		if yobSet {
			err = store.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(yob))
			if err != nil {
				logg.ErrorCtxf(ctx, "failed to write temporaryYob entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", yob, "error", err)
				return res, err
			}
		} else {
			h.profile.InsertOrShift(3, yob)
		}
	}

	return res, nil
}

// SaveLocation updates the location in the gdbm with the provided input.
func (h *MenuHandlers) SaveLocation(ctx context.Context, sym string, input []byte) (resource.Result, error) {
	var res resource.Result
	var err error
	sessionId, ok := ctx.Value("SessionId").(string)
	if !ok {
		return res, fmt.Errorf("missing session")
	}
	location := string(input)
	store := h.userdataStore
	logdb := h.logDb

	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
	flag_location_set, _ := h.flagManager.GetFlag("flag_location_set")
	allowUpdate := h.st.MatchFlag(flag_allow_update, true)
	locationSet := h.st.MatchFlag(flag_location_set, true)

	if allowUpdate {
		temporaryLocation, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
		if len(temporaryLocation) == 0 {
			logg.ErrorCtxf(ctx, "temporaryLocation is empty", "key", storedb.DATA_TEMPORARY_VALUE)
			return res, fmt.Errorf("Data error encountered")
		}
		err = store.WriteEntry(ctx, sessionId, storedb.DATA_LOCATION, []byte(temporaryLocation))
		if err != nil {
			logg.ErrorCtxf(ctx, "failed to write location entry with", "key", storedb.DATA_LOCATION, "value", temporaryLocation, "error", err)
			return res, err
		}
		res.FlagSet = append(res.FlagSet, flag_location_set)

		err = logdb.WriteLogEntry(ctx, sessionId, storedb.DATA_LOCATION, []byte(temporaryLocation))
		if err != nil {
			logg.DebugCtxf(ctx, "Failed to write location db log entry", "key", storedb.DATA_LOCATION, "value", temporaryLocation)
		}
	} else {
		if locationSet {
			err = store.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(location))
			if err != nil {
				logg.ErrorCtxf(ctx, "failed to write temporaryLocation entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", location, "error", err)
				return res, err
			}
			res.FlagSet = append(res.FlagSet, flag_location_set)
		} else {
			h.profile.InsertOrShift(4, location)
		}
	}

	return res, nil
}

// SaveGender updates the gender in the gdbm with the provided input.
func (h *MenuHandlers) SaveGender(ctx context.Context, sym string, input []byte) (resource.Result, error) {
	symbol, _ := h.st.Where()
	var res resource.Result
	var err error
	sessionId, ok := ctx.Value("SessionId").(string)
	if !ok {
		return res, fmt.Errorf("missing session")
	}
	gender := strings.Split(symbol, "_")[1]
	store := h.userdataStore
	logdb := h.logDb
	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
	flag_gender_set, _ := h.flagManager.GetFlag("flag_gender_set")

	allowUpdate := h.st.MatchFlag(flag_allow_update, true)
	genderSet := h.st.MatchFlag(flag_gender_set, true)

	if allowUpdate {
		temporaryGender, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
		if len(temporaryGender) == 0 {
			logg.ErrorCtxf(ctx, "temporaryGender is empty", "key", storedb.DATA_TEMPORARY_VALUE)
			return res, fmt.Errorf("Data error encountered")
		}
		err = store.WriteEntry(ctx, sessionId, storedb.DATA_GENDER, []byte(temporaryGender))
		if err != nil {
			logg.ErrorCtxf(ctx, "failed to write gender entry with", "key", storedb.DATA_GENDER, "value", gender, "error", err)
			return res, err
		}
		res.FlagSet = append(res.FlagSet, flag_gender_set)

		err = logdb.WriteLogEntry(ctx, sessionId, storedb.DATA_GENDER, []byte(temporaryGender))
		if err != nil {
			logg.DebugCtxf(ctx, "Failed to write gender db log entry", "key", storedb.DATA_TEMPORARY_VALUE, "value", temporaryGender)
		}

	} else {
		if genderSet {
			err = store.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(gender))
			if err != nil {
				logg.ErrorCtxf(ctx, "failed to write temporaryGender entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", gender, "error", err)
				return res, err
			}
		} else {
			h.profile.InsertOrShift(2, gender)
		}
	}

	return res, nil
}

// SaveOfferings updates the offerings(goods and services provided by the user) in the gdbm with the provided input.
func (h *MenuHandlers) SaveOfferings(ctx context.Context, sym string, input []byte) (resource.Result, error) {
	var res resource.Result
	var err error
	sessionId, ok := ctx.Value("SessionId").(string)
	if !ok {
		return res, fmt.Errorf("missing session")
	}

	offerings := string(input)
	store := h.userdataStore
	logdb := h.logDb

	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
	flag_offerings_set, _ := h.flagManager.GetFlag("flag_offerings_set")

	allowUpdate := h.st.MatchFlag(flag_allow_update, true)
	offeringsSet := h.st.MatchFlag(flag_offerings_set, true)

	if allowUpdate {
		temporaryOfferings, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
		if len(temporaryOfferings) == 0 {
			logg.ErrorCtxf(ctx, "temporaryOfferings is empty", "key", storedb.DATA_TEMPORARY_VALUE)
			return res, fmt.Errorf("Data error encountered")
		}
		err = store.WriteEntry(ctx, sessionId, storedb.DATA_OFFERINGS, []byte(temporaryOfferings))
		if err != nil {
			logg.ErrorCtxf(ctx, "failed to write offerings entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", offerings, "error", err)
			return res, err
		}
		res.FlagSet = append(res.FlagSet, flag_offerings_set)

		err = logdb.WriteLogEntry(ctx, sessionId, storedb.DATA_FIRST_NAME, []byte(temporaryOfferings))
		if err != nil {
			logg.DebugCtxf(ctx, "Failed to write offerings db log entry", "key", storedb.DATA_OFFERINGS, "value", offerings)
		}
	} else {
		if offeringsSet {
			err = store.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(offerings))
			if err != nil {
				logg.ErrorCtxf(ctx, "failed to write temporaryOfferings entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", offerings, "error", err)
				return res, err
			}
		} else {
			h.profile.InsertOrShift(5, offerings)
		}
	}

	return res, nil
}

// GetCurrentProfileInfo retrieves specific profile fields based on the current state of the USSD session.
// Uses flag management system to track profile field status and handle menu navigation.
func (h *MenuHandlers) GetCurrentProfileInfo(ctx context.Context, sym string, input []byte) (resource.Result, error) {
	var res resource.Result
	var profileInfo []byte
	var defaultValue string
	var err error

	flag_firstname_set, _ := h.flagManager.GetFlag("flag_firstname_set")
	flag_familyname_set, _ := h.flagManager.GetFlag("flag_familyname_set")
	flag_yob_set, _ := h.flagManager.GetFlag("flag_yob_set")
	flag_gender_set, _ := h.flagManager.GetFlag("flag_gender_set")
	flag_location_set, _ := h.flagManager.GetFlag("flag_location_set")
	flag_offerings_set, _ := h.flagManager.GetFlag("flag_offerings_set")
	flag_back_set, _ := h.flagManager.GetFlag("flag_back_set")

	res.FlagReset = append(res.FlagReset, flag_back_set)

	sessionId, ok := ctx.Value("SessionId").(string)
	if !ok {
		return res, fmt.Errorf("missing session")
	}
	language, ok := ctx.Value("Language").(lang.Language)
	if !ok {
		return res, fmt.Errorf("value for 'Language' is not of type lang.Language")
	}
	code := language.Code
	if code == "swa" {
		defaultValue = "Haipo"
	} else {
		defaultValue = "Not Provided"
	}

	sm, _ := h.st.Where()
	parts := strings.SplitN(sm, "_", 2)
	filename := parts[1]
	dbKeyStr := "DATA_" + strings.ToUpper(filename)
	logg.InfoCtxf(ctx, "GetCurrentProfileInfo", "filename", filename, "dbKeyStr:", dbKeyStr)
	dbKey, err := storedb.StringToDataTyp(dbKeyStr)

	if err != nil {
		return res, err
	}
	store := h.userdataStore

	switch dbKey {
	case storedb.DATA_FIRST_NAME:
		profileInfo, err = store.ReadEntry(ctx, sessionId, storedb.DATA_FIRST_NAME)
		if err != nil {
			if db.IsNotFound(err) {
				res.Content = defaultValue
				break
			}
			logg.ErrorCtxf(ctx, "Failed to read first name entry with", "key", "error", storedb.DATA_FIRST_NAME, err)
			return res, err
		}
		res.FlagSet = append(res.FlagSet, flag_firstname_set)
		res.Content = string(profileInfo)
	case storedb.DATA_FAMILY_NAME:
		profileInfo, err = store.ReadEntry(ctx, sessionId, storedb.DATA_FAMILY_NAME)
		if err != nil {
			if db.IsNotFound(err) {
				res.Content = defaultValue
				break
			}
			logg.ErrorCtxf(ctx, "Failed to read family name entry with", "key", "error", storedb.DATA_FAMILY_NAME, err)
			return res, err
		}
		res.FlagSet = append(res.FlagSet, flag_familyname_set)
		res.Content = string(profileInfo)

	case storedb.DATA_GENDER:
		profileInfo, err = store.ReadEntry(ctx, sessionId, storedb.DATA_GENDER)
		if err != nil {
			if db.IsNotFound(err) {
				res.Content = defaultValue
				break
			}
			logg.ErrorCtxf(ctx, "Failed to read gender entry with", "key", "error", storedb.DATA_GENDER, err)
			return res, err
		}
		res.FlagSet = append(res.FlagSet, flag_gender_set)
		res.Content = string(profileInfo)
	case storedb.DATA_YOB:
		profileInfo, err = store.ReadEntry(ctx, sessionId, storedb.DATA_YOB)
		if err != nil {
			if db.IsNotFound(err) {
				res.Content = defaultValue
				break
			}
			logg.ErrorCtxf(ctx, "Failed to read year of birth(yob) entry with", "key", "error", storedb.DATA_YOB, err)
			return res, err
		}
		res.FlagSet = append(res.FlagSet, flag_yob_set)
		res.Content = string(profileInfo)
	case storedb.DATA_LOCATION:
		profileInfo, err = store.ReadEntry(ctx, sessionId, storedb.DATA_LOCATION)
		if err != nil {
			if db.IsNotFound(err) {
				res.Content = defaultValue
				break
			}
			logg.ErrorCtxf(ctx, "Failed to read location entry with", "key", "error", storedb.DATA_LOCATION, err)
			return res, err
		}
		res.FlagSet = append(res.FlagSet, flag_location_set)
		res.Content = string(profileInfo)
	case storedb.DATA_OFFERINGS:
		profileInfo, err = store.ReadEntry(ctx, sessionId, storedb.DATA_OFFERINGS)
		if err != nil {
			if db.IsNotFound(err) {
				res.Content = defaultValue
				break
			}
			logg.ErrorCtxf(ctx, "Failed to read offerings entry with", "key", "error", storedb.DATA_OFFERINGS, err)
			return res, err
		}
		res.FlagSet = append(res.FlagSet, flag_offerings_set)
		res.Content = string(profileInfo)
	case storedb.DATA_ACCOUNT_ALIAS:
		profileInfo, err = store.ReadEntry(ctx, sessionId, storedb.DATA_ACCOUNT_ALIAS)
		if err != nil {
			if db.IsNotFound(err) {
				res.Content = defaultValue
				break
			}
			logg.ErrorCtxf(ctx, "Failed to read account alias entry with", "key", "error", storedb.DATA_ACCOUNT_ALIAS, err)
			return res, err
		}
		alias := string(profileInfo)
		if alias == "" {
			res.Content = defaultValue
		} else {
			res.Content = alias
		}
	default:
		break
	}

	return res, nil
}

// GetProfileInfo provides a comprehensive view of a user's profile.
func (h *MenuHandlers) GetProfileInfo(ctx context.Context, sym string, input []byte) (resource.Result, error) {
	var res resource.Result
	var defaultValue string
	sessionId, ok := ctx.Value("SessionId").(string)
	if !ok {
		return res, fmt.Errorf("missing session")
	}
	language, ok := ctx.Value("Language").(lang.Language)
	if !ok {
		return res, fmt.Errorf("value for 'Language' is not of type lang.Language")
	}
	code := language.Code
	if code == "swa" {
		defaultValue = "Haipo"
	} else {
		defaultValue = "Not Provided"
	}

	// Helper function to handle nil byte slices and convert them to string
	getEntryOrDefault := func(entry []byte, err error) string {
		if err != nil || entry == nil {
			return defaultValue
		}
		return string(entry)
	}
	store := h.userdataStore
	// Retrieve user data as strings with fallback to defaultValue
	firstName := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_FIRST_NAME))
	familyName := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_FAMILY_NAME))
	yob := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_YOB))
	gender := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_GENDER))
	location := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_LOCATION))
	offerings := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_OFFERINGS))
	alias := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_ACCOUNT_ALIAS))

	if alias != defaultValue && alias != "" {
		alias = strings.Split(alias, ".")[0]
	} else {
		alias = defaultValue
	}

	// Construct the full name
	name := person.ConstructName(firstName, familyName, defaultValue)

	// Calculate age from year of birth
	age := defaultValue
	if yob != defaultValue {
		if yobInt, err := strconv.Atoi(yob); err == nil {
			age = strconv.Itoa(person.CalculateAgeWithYOB(yobInt))
		} else {
			return res, fmt.Errorf("invalid year of birth: %v", err)
		}
	}
	switch language.Code {
	case "eng":
		res.Content = fmt.Sprintf(
			"Name: %s\nGender: %s\nAge: %s\nLocation: %s\nYou provide: %s\nYour alias: %s\n",
			name, gender, age, location, offerings, alias,
		)
	case "swa":
		res.Content = fmt.Sprintf(
			"Jina: %s\nJinsia: %s\nUmri: %s\nEneo: %s\nUnauza: %s\nLakabu yako: %s\n",
			name, gender, age, location, offerings, alias,
		)
	default:
		res.Content = fmt.Sprintf(
			"Name: %s\nGender: %s\nAge: %s\nLocation: %s\nYou provide: %s\nYour alias: %s\n",
			name, gender, age, location, offerings, alias,
		)
	}

	return res, nil
}

// handles bulk updates of profile information.
func (h *MenuHandlers) insertProfileItems(ctx context.Context, sessionId string, res *resource.Result) error {
	var err error
	userStore := h.userdataStore
	profileFlagNames := []string{
		"flag_firstname_set",
		"flag_familyname_set",
		"flag_yob_set",
		"flag_gender_set",
		"flag_location_set",
		"flag_offerings_set",
	}
	profileDataKeys := []storedb.DataTyp{
		storedb.DATA_FIRST_NAME,
		storedb.DATA_FAMILY_NAME,
		storedb.DATA_GENDER,
		storedb.DATA_YOB,
		storedb.DATA_LOCATION,
		storedb.DATA_OFFERINGS,
	}
	for index, profileItem := range h.profile.ProfileItems {
		// Ensure the profileItem is not "0"(is set)
		if profileItem != "0" {
			flag, _ := h.flagManager.GetFlag(profileFlagNames[index])
			isProfileItemSet := h.st.MatchFlag(flag, true)
			if !isProfileItemSet {
				err = userStore.WriteEntry(ctx, sessionId, profileDataKeys[index], []byte(profileItem))
				if err != nil {
					logg.ErrorCtxf(ctx, "failed to write profile entry with", "key", profileDataKeys[index], "value", profileItem, "error", err)
					return err
				}
				res.FlagSet = append(res.FlagSet, flag)
			}
		}
	}
	return nil
}

// UpdateAllProfileItems  is used to persist all the  new profile information and setup  the required profile flags.
func (h *MenuHandlers) UpdateAllProfileItems(ctx context.Context, sym string, input []byte) (resource.Result, error) {
	var res resource.Result
	sessionId, ok := ctx.Value("SessionId").(string)
	if !ok {
		return res, fmt.Errorf("missing session")
	}
	err := h.insertProfileItems(ctx, sessionId, &res)
	if err != nil {
		return res, err
	}
	return res, nil
}
