package person

import (
	ecore "simrs-vx/internal/domain/base-entities/core"
	evm "simrs-vx/internal/domain/bpjs-entities/vclaim-member"
	ee "simrs-vx/internal/domain/main-entities/ethnic"
	el "simrs-vx/internal/domain/main-entities/language"
	epa "simrs-vx/internal/domain/main-entities/person-address"
	epc "simrs-vx/internal/domain/main-entities/person-contact"
	epi "simrs-vx/internal/domain/main-entities/person-insurance"
	epr "simrs-vx/internal/domain/main-entities/person-relative"
	er "simrs-vx/internal/domain/main-entities/regency"
	"strings"

	erp "simrs-vx/internal/domain/references/person"

	"time"
)

type Person struct {
	ecore.Main                                      // adjust this according to the needs
	Name                     string                 `json:"name" gorm:"not null;size:150"`
	FrontTitle               *string                `json:"frontTitle" gorm:"size:50"`
	EndTitle                 *string                `json:"endTitle" gorm:"size:50"`
	BirthDate                *time.Time             `json:"birthDate,omitempty"`
	BirthRegency_Code        *string                `json:"birthRegency_code" gorm:"size:4"`
	BirthRegency             *er.Regency            `json:"birthRegency,omitempty" gorm:"foreignKey:BirthRegency_Code;references:Code"`
	Gender_Code              *erp.GenderCode        `json:"gender_code" gorm:"size:10"`
	ResidentIdentityNumber   *string                `json:"residentIdentityNumber" gorm:"uniqueIndex:idx_resident_identity,where:\"DeletedAt\" IS NULL;size:16"`
	PassportNumber           *string                `json:"passportNumber" gorm:"uniqueIndex:idx_passport,where:\"DeletedAt\" IS NULL;size:20"`
	DrivingLicenseNumber     *string                `json:"drivingLicenseNumber" gorm:"uniqueIndex:idx_driver_license,where:\"DeletedAt\" IS NULL;size:20"`
	Religion_Code            *erp.ReligionCode      `json:"religion_code" gorm:"size:10"`
	Confidence               *string                `json:"confidence" gorm:"size:512"`
	Education_Code           *erp.EducationCode     `json:"education_code" gorm:"size:10"`
	Ocupation_Code           *erp.OcupationCode     `json:"occupation_code" gorm:"size:15"`
	Ocupation_Name           *string                `json:"occupation_name" gorm:"size:50"`
	MaritalStatus_Code       *erp.MaritalStatusCode `json:"maritalStatus_code" gorm:"size:10"`
	Nationality              *string                `json:"nationality" gorm:"size:50"`
	Ethnic_Code              *string                `json:"ethnic_code" gorm:"size:20"`
	Ethnic                   *ee.Ethnic             `json:"ethnic,omitempty" gorm:"foreignKey:Ethnic_Code;references:Code"`
	Language_Code            *string                `json:"language_code" gorm:"size:10"`
	Language                 *el.Language           `json:"language,omitempty" gorm:"foreignKey:Language_Code;references:Code"`
	CommunicationIssueStatus bool                   `json:"communicationIssueStatus"`
	Disability               *string                `json:"disability" gorm:"size:100"`
	ResidentIdentityFileUrl  *string                `json:"residentIdentityFileUrl" gorm:"size:1024"`
	PassportFileUrl          *string                `json:"passportFileUrl" gorm:"size:1024"`
	DrivingLicenseFileUrl    *string                `json:"drivingLicenseFileUrl" gorm:"size:1024"`
	FamilyIdentityFileUrl    *string                `json:"familyIdentityFileUrl" gorm:"size:1024"`
	Addresses                *[]epa.PersonAddress   `json:"addresses" gorm:"foreignKey:Person_Id"`
	Contacts                 *[]epc.PersonContact   `json:"contacts" gorm:"foreignKey:Person_Id"`
	Relatives                *[]epr.PersonRelative  `json:"relatives" gorm:"foreignKey:Person_Id"`
	Insurances               *[]epi.PersonInsurance `json:"insurances" gorm:"foreignKey:Person_Id"`
	VclaimMember             *evm.VclaimMember      `json:"vclaimMember,omitempty" gorm:"foreignKey:Person_Id;references:Id"`
}

func (d Person) IsSameResidentIdentityNumber(input *string) bool {
	if input == nil {
		return false
	}
	return d.ResidentIdentityNumber == input
}

func (d Person) GenderString() string {
	if d.Gender_Code == nil {
		return ""
	}
	switch *d.Gender_Code {
	case erp.GCMale:
		return "Laki-laki(L)"
	case erp.GCFemale:
		return "Perempuan(P)"
	default:
		return ""
	}
}

func (d Person) GetPhoneNumber() string {
	if d.Contacts == nil {
		return ""
	}
	for _, c := range *d.Contacts {
		if c.Type_Code == erp.CTPhone || c.Type_Code == erp.CTMPhone {
			return c.Value
		}
	}
	return ""
}

func (d Person) FullName() string {
	name := strings.TrimSpace(d.Name)
	if name == "" {
		return ""
	}

	parts := []string{}

	// Front title (dr., drs., etc)
	if d.FrontTitle != nil {
		ft := strings.TrimSpace(*d.FrontTitle)
		if ft != "" {
			parts = append(parts, ft)
		}
	}

	// Name (always included)
	parts = append(parts, name)

	// Join front title + name
	full := strings.Join(parts, " ")

	// End title → attach with comma
	if d.EndTitle != nil {
		et := strings.TrimSpace(*d.EndTitle)
		if et != "" {
			full = full + ", " + et
		}
	}

	return full
}
