/*
DESCRIPTION:
Any functions that are used internally by the use-case
*/
package patient

import (
	"fmt"
	"strconv"
	"time"

	e "simrs-vx/internal/domain/main-entities/patient"
	ibpjs "simrs-vx/internal/infra/bpjs"

	dg "github.com/karincake/apem/db-gorm-pg"
)

func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Patient) error {
	var inputSrc *e.CreateDto
	if inputT, ok := any(input).(*e.CreateDto); ok {
		inputSrc = inputT
		data.RegisteredBy_User_Name = inputSrc.RegisteredBy_User_Name
	} else {
		inputTemp := any(input).(*e.UpdateDto)
		inputSrc = &inputTemp.CreateDto
	}

	switch {
	case inputSrc.Number == nil && data.Number == nil:
		medRecNum, err := GenerateNextMedicalRecordNumber()
		if err != nil {
			return err
		}
		data.Number = &medRecNum
	case inputSrc.Number != nil:
		data.Number = inputSrc.Number
	}

	data.Person_Id = inputSrc.Person_Id
	data.RegisteredAt = inputSrc.RegisteredAt
	data.Status_Code = inputSrc.Status_Code
	data.NewBornStatus = inputSrc.NewBornStatus
	return nil
}

func GenerateNextMedicalRecordNumber() (string, error) {
	var last string
	err := dg.I.
		Table("\"Patient\"").
		Select("\"Number\"").
		Where("\"Number\" IS NOT NULL AND \"Number\" ~ '^[0-9]+$'"). // Only numeric strings
		Order("\"Number\"::bigint DESC").
		Limit(1).
		Scan(&last).Error
	if err != nil {
		return "", err
	}

	//var nextInt int64
	//var format string

	//if last == "" {
	//	// No existing records, start with 10 digits
	//	nextInt = 1
	//	format = "%08d"
	//} else {
	//	n, err := strconv.ParseInt(last, 10, 64)
	//	if err != nil {
	//		return "", err
	//	}
	//	nextInt = n + 1
	//
	//	// Dynamically determine format based on existing number
	//	digitCount := len(last)
	//
	//	// If the incremented number needs more digits, expand format
	//	nextStr := strconv.FormatInt(nextInt, 10)
	//	if len(nextStr) > digitCount {
	//		digitCount = len(nextStr)
	//	}
	//
	//	// Ensure minimum 10 digits as per requirement
	//	if digitCount < 10 {
	//		digitCount = 10
	//	}
	//
	//	format = fmt.Sprintf("%%0%dd", digitCount)
	//}

	const prefix = "12" // fixed starting prefix (same as $awal_rm) in simgos
	const maxSuffix = 999999

	// No existing NOMR → start fresh
	if last == "" {
		return prefix + "000001", nil
	}

	suffix := last[len(prefix):] // extract numeric part
	num, _ := strconv.Atoi(suffix)

	// 3. If suffix reaches 999999 → increment the prefix
	if num == maxSuffix {
		p, _ := strconv.Atoi(prefix)
		p++
		return fmt.Sprintf("%d000001", p), nil
	}

	// 4. Normal increment
	return prefix + fmt.Sprintf("%06d", num+1), nil
}

func endpointMapper(noBpjs string) string {
	today := getTodayDate()
	return fmt.Sprintf("%speserta/nokartu?noKartu=%s&tglpelayanan=%s", ibpjs.O.BaseUrl, noBpjs, today)

}

func getTodayDate() string {
	return time.Now().Format("2006-01-02")
}
