package polygenicDiseases

import "seekia/internal/helpers"

import _ "embed"

import "errors"
import "encoding/gob"
import "bytes"
import "maps"


//go:embed rsIDs/GiantObesityStudyLoci.gob
var GiantObesityStudyLociFile []byte


func getObesityDiseaseObject()(PolygenicDisease, error){

	// Map Structure: rsID -> References Map
	locusReferencesMap := make(map[int64]map[string]string)


	locus1_ReferencesMap := make(map[string]string)
	locus1_ReferencesMap["SNPedia.com - rs5082"] = "https://snpedia.com/index.php/Rs5082"

	locusReferencesMap[5082] = locus1_ReferencesMap

	locus2_ReferencesMap := make(map[string]string)
	locus2_ReferencesMap["SNPedia.com - rs6413453"] = "https://snpedia.com/index.php/Rs6413453"

	locusReferencesMap[6413453] = locus2_ReferencesMap

	locus3_ReferencesMap := make(map[string]string)
	locus3_ReferencesMap["SNPedia.com - rs9939609"] = "https://snpedia.com/index.php/Rs9939609"

	locusReferencesMap[9939609] = locus3_ReferencesMap

	locus4_ReferencesMap := make(map[string]string)
	locus4_ReferencesMap["SNPedia.com - rs1121980"] = "https://snpedia.com/index.php/Rs1121980"

	locusReferencesMap[1121980] = locus4_ReferencesMap


	//TODO:
	//	https://snpedia.com/index.php/Rs662799
	//	https://snpedia.com/index.php/Rs2229616
	//	https://snpedia.com/index.php/Rs16964465
	//	https://snpedia.com/index.php/Rs16964476
	//	https://snpedia.com/index.php/Rs3764220
	//	https://snpedia.com/index.php/Rs1528133
	//	https://snpedia.com/index.php/Rs2272382
	//	https://snpedia.com/index.php/Rs2272383
	//	https://snpedia.com/index.php/Rs1851665
	//	https://snpedia.com/index.php/Rs11924390
	//	https://snpedia.com/index.php/Rs3865188
	//	https://snpedia.com/index.php/Rs864265
	//	https://snpedia.com/index.php/Rs266717
	//	https://snpedia.com/index.php/Rs11924390
	//	https://snpedia.com/index.php/Rs7193788
	//	https://snpedia.com/index.php/Rs6444175
	//	https://snpedia.com/index.php/Rs4311394
	//	https://snpedia.com/index.php/Rs6971091


	referencesMap_List1 := make(map[string]string)
	referencesMap_List1["GIANT consortium - Meta-analyses of Genome-Wide Association Studies - 2022 - Obesity"] = "https://portals.broadinstitute.org/collaboration/giant/index.php/GIANT_consortium_data_files"

	// These SNPs are taken from the meta-analyses of Genome-Wide Association Studies (GWAS) created by the GIANT consortium
	//https://portals.broadinstitute.org/collaboration/giant/index.php/GIANT_consortium_data_files

	// Download link:
	// https://portals.broadinstitute.org/collaboration/giant/images/0/09/PublicRelease.WHRadjBMI.C.All.Add.txt.gz

	// SHA-256 Checksum:
	// 2a863b0357037ae5c34853342052ed3c59735d6440da0fd15d1cab34b7d49daf

	// See /utilities/extractGiantLoci/extractGiantLoci.go to see how they were extracted from the file

	buffer := bytes.NewBuffer(GiantObesityStudyLociFile)
	decoder := gob.NewDecoder(buffer)

	var lociList_1 []int64

	err := decoder.Decode(&lociList_1)
	if (err != nil){ return PolygenicDisease{}, err }

	for _, rsID := range lociList_1{

		existingMap, exists := locusReferencesMap[rsID]
		if (exists == false){
			locusReferencesMap[rsID] = maps.Clone(referencesMap_List1)
		} else {
			// We merge the referencesMaps
			for key, value := range referencesMap_List1{
				existingMap[key] = value
			}
			locusReferencesMap[rsID] = existingMap
		}
	}

	obesityLociList := helpers.GetListOfMapKeys(locusReferencesMap)

	referencesMap := make(map[string]string)
	referencesMap["Obesity Genome-Wide Association Study (GWAS) created by the GIANT consortium"] = "https://portals.broadinstitute.org/collaboration/giant/index.php/GIANT_consortium_data_files"
	referencesMap["Obesity - SNPedia"] = "https://snpedia.com/index.php/Obesity"

	getAverageRiskProbabilitiesFunction := func(maleOrFemale string, inputAge int)(float64, error){

		// Roughly 30% of people are obese.

		if (maleOrFemale == "Male"){
			return 0.30, nil
		}

		if (maleOrFemale != "Female"){
			return 0, errors.New("Trying to get obesity risk probability for invalid maleOrFemale: " + maleOrFemale)
		}

		//TODO: Add different probabilities per age

		return 0.30, nil
	}

	obesityObject := PolygenicDisease{
		DiseaseName: "Obesity",
		EffectedSex: "Both",
		DiseaseDescription: "The condition of having an excessive amount of body fat.",
		LocusReferencesMap: locusReferencesMap,
		LociList: obesityLociList,
		GetAverageRiskProbabilitiesFunction: getAverageRiskProbabilitiesFunction,
		References: referencesMap,
	}

	return obesityObject, nil
}


