package person

import (
	"time"

	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"
	epa "simrs-vx/internal/domain/main-entities/person-address"
	epc "simrs-vx/internal/domain/main-entities/person-contact"
	epr "simrs-vx/internal/domain/main-entities/person-relative"
	er "simrs-vx/internal/domain/main-entities/regency"

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

type CreateDto struct {
	Name                     string                 `json:"name" validate:"maxLength=150"`
	FrontTitle               *string                `json:"frontTitle" validate:"maxLength=50"`
	EndTitle                 *string                `json:"endTitle" validate:"maxLength=50"`
	BirthDate                *time.Time             `json:"birthDate,omitempty"`
	BirthRegency_Code        *string                `json:"birthRegency_code" validate:"maxLength=4"`
	Gender_Code              *erp.GenderCode        `json:"gender_code"`
	ResidentIdentityNumber   *string                `json:"residentIdentityNumber" validate:"nik;maxLength=16"`
	PassportNumber           *string                `json:"passportNumber" validate:"maxLength=20"`
	DrivingLicenseNumber     *string                `json:"drivingLicenseNumber" validate:"maxLength=20"`
	Religion_Code            *erp.ReligionCode      `json:"religion_code" validate:"maxLength=10"`
	Education_Code           *erp.EducationCode     `json:"education_code" validate:"maxLength=10"`
	Ocupation_Code           *erp.OcupationCode     `json:"occupation_code" validate:"maxLength=15"`
	Ocupation_Name           *string                `json:"occupation_name" validate:"maxLength=50"`
	MaritalStatus_Code       *erp.MaritalStatusCode `json:"maritalStatus_code" validate:"maxLength=10"`
	Confidence               *string                `json:"confidence" validate:"maxLength=512"`
	Nationality              *string                `json:"nationality" validate:"maxLength=50"`
	Ethnic_Code              *string                `json:"ethnic_code" validate:"maxLength=20"`
	Language_Code            *string                `json:"language_code" validate:"maxLength=10"`
	CommunicationIssueStatus bool                   `json:"communicationIssueStatus"`
	Disability               *string                `json:"disability" validate:"maxLength=100"`
	VclaimMember_CardNumber  *string                `json:"vclaimMember_cardNumber" validate:"maxLength=20"`
}

type ReadListDto struct {
	FilterDto
	Includes   string `json:"includes"`
	Pagination ecore.Pagination
}

type FilterDto struct {
	Name                     string             `json:"name"`
	FrontTitle               *string            `json:"frontTitle"`
	EndTitle                 *string            `json:"endTitle"`
	BirthDate                *time.Time         `json:"birthDate,omitempty"`
	BirthRegency_Code        *string            `json:"birthRegency-code"`
	Gender_Code              *erp.GenderCode    `json:"gender-code"`
	ResidentIdentityNumber   *string            `json:"residentIdentityNumber"`
	PassportNumber           *string            `json:"passportNumber"`
	DrivingLicenseNumber     *string            `json:"drivingLicenseNumber"`
	Religion_Code            *erp.ReligionCode  `json:"religion-code"`
	Education_Code           *erp.EducationCode `json:"education-code"`
	Ocupation_Code           *erp.OcupationCode `json:"occupation-code"`
	Ocupation_Name           *string            `json:"occupation-name"`
	Nationality              *string            `json:"nationality"`
	Ethnic_Code              *string            `json:"ethnic-code"`
	Language_Code            *string            `json:"language-code"`
	CommunicationIssueStatus bool               `json:"communicationIssueStatus"`
	Disability               *string            `json:"disability"`
}

type ReadDetailDto struct {
	Id                     uint    `json:"id"`
	Name                   *string `json:"name"`
	ResidentIdentityNumber *string `json:"residentIdentityNumber"`
	PassportNumber         *string `json:"passportNumber"`
	DrivingLicenseNumber   *string `json:"drivingLicenseNumber"`
}

type UpdateDto struct {
	Id uint `json:"id"`
	CreateDto
}

type DeleteDto struct {
	Id uint `json:"id"`
}

type MetaDto struct {
	PageNumber int `json:"page_number"`
	PageSize   int `json:"page_size"`
	Count      int `json:"count"`
}

type ResponseDto struct {
	ecore.Main
	Name                     string                 `json:"name"`
	FrontTitle               *string                `json:"frontTitle"`
	EndTitle                 *string                `json:"endTitle"`
	BirthDate                *time.Time             `json:"birthDate,omitempty"`
	BirthRegency_Code        *string                `json:"birthRegency_code"`
	BirthRegency             *er.Regency            `json:"birthRegency,omitempty"`
	Gender_Code              *erp.GenderCode        `json:"gender_code"`
	ResidentIdentityNumber   *string                `json:"residentIdentityNumber"`
	PassportNumber           *string                `json:"passportNumber"`
	DrivingLicenseNumber     *string                `json:"drivingLicenseNumber"`
	Religion_Code            *erp.ReligionCode      `json:"religion_code"`
	Education_Code           *erp.EducationCode     `json:"education_code"`
	Ocupation_Code           *erp.OcupationCode     `json:"occupation_code"`
	Ocupation_Name           *string                `json:"occupation_name"`
	MaritalStatus_Code       *erp.MaritalStatusCode `json:"maritalStatus_code"`
	Confidence               *string                `json:"confidence"`
	Nationality              *string                `json:"nationality"`
	Ethnic_Code              *string                `json:"ethnic_code"`
	Ethnic                   *ee.Ethnic             `json:"ethnic,omitempty"`
	Addresses                *[]epa.PersonAddress   `json:"addresses,omitempty"`
	Contacts                 *[]epc.PersonContact   `json:"contacts,omitempty"`
	Relatives                *[]epr.PersonRelative  `json:"relatives,omitempty"`
	Language_Code            *string                `json:"language_code"`
	CommunicationIssueStatus bool                   `json:"communicationIssueStatus"`
	Disability               *string                `json:"disability"`
	ResidentIdentityFileUrl  *string                `json:"residentIdentityFileUrl"`
	PassportFileUrl          *string                `json:"passportFileUrl"`
	DrivingLicenseFileUrl    *string                `json:"drivingLicenseFileUrl"`
	FamilyIdentityFileUrl    *string                `json:"familyIdentityFileUrl"`
	VclaimMember             *evm.VclaimMember      `json:"vclaimMember,omitempty"`
}

func (d *Person) ToResponse() ResponseDto {
	resp := ResponseDto{
		Name:                     d.Name,
		FrontTitle:               d.FrontTitle,
		EndTitle:                 d.EndTitle,
		BirthDate:                d.BirthDate,
		BirthRegency_Code:        d.BirthRegency_Code,
		BirthRegency:             d.BirthRegency,
		Gender_Code:              d.Gender_Code,
		ResidentIdentityNumber:   d.ResidentIdentityNumber,
		PassportNumber:           d.PassportNumber,
		DrivingLicenseNumber:     d.DrivingLicenseNumber,
		Religion_Code:            d.Religion_Code,
		Education_Code:           d.Education_Code,
		Ocupation_Code:           d.Ocupation_Code,
		Ocupation_Name:           d.Ocupation_Name,
		MaritalStatus_Code:       d.MaritalStatus_Code,
		Confidence:               d.Confidence,
		Nationality:              d.Nationality,
		Ethnic_Code:              d.Ethnic_Code,
		Ethnic:                   d.Ethnic,
		Addresses:                d.Addresses,
		Contacts:                 d.Contacts,
		Relatives:                d.Relatives,
		Language_Code:            d.Language_Code,
		CommunicationIssueStatus: d.CommunicationIssueStatus,
		Disability:               d.Disability,
		ResidentIdentityFileUrl:  d.ResidentIdentityFileUrl,
		PassportFileUrl:          d.PassportFileUrl,
		DrivingLicenseFileUrl:    d.DrivingLicenseFileUrl,
		FamilyIdentityFileUrl:    d.FamilyIdentityFileUrl,
		VclaimMember:             d.VclaimMember,
	}
	resp.Main = d.Main
	return resp
}

func ToResponseList(data []Person) []ResponseDto {
	resp := make([]ResponseDto, len(data))
	for i, u := range data {
		resp[i] = u.ToResponse()
	}
	return resp
}
