package dto

import (
	"time"

	entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
	areaBaseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/areas/dto"
	fcrBaseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs/dto"
	flockBaseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto"
	kandangBaseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/dto"
	locationBaseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations/dto"
	userBaseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
)

// === DTO Structs (ordered) ===

type ChickinBaseDTO struct {
	Id                  uint                    `json:"id"`
	ProjectFlockKandang *ProjectFlockKandangDTO `json:"project_flock_kandang"`
	ChickInDate         time.Time               `json:"chick_in_date"`
	Quantity            float64                 `json:"quantity"`
	Note                string                  `json:"note"`
}

type ProjectFlockDTO struct {
	Id       uint                             `json:"id"`
	Period   int                              `json:"period"`
	Category string                           `json:"category"`
	Flock    *flockBaseDTO.FlockBaseDTO       `json:"flock"`
	Area     *areaBaseDTO.AreaBaseDTO         `json:"area"`
	Fcr      *fcrBaseDTO.FcrBaseDTO           `json:"fcr"`
	Location *locationBaseDTO.LocationBaseDTO `json:"location"`
}

type ProjectFlockKandangDTO struct {
	Id           uint                           `json:"id"`
	ProjectFlock *ProjectFlockDTO               `json:"project_flock"`
	Kandang      *kandangBaseDTO.KandangBaseDTO `json:"kandang"`
}

// gunakan base DTO dari package users

type ChickinSimpleDTO struct {
	Id                    uint      `json:"id"`
	ProjectFlockKandangId uint      `json:"project_flock_kandang_id"`
	ChickInDate           time.Time `json:"chick_in_date"`
	Quantity              float64   `json:"quantity"`
	Note                  string    `json:"note"`
	CreatedBy             uint      `json:"created_by"`
}

type ChickinListDTO struct {
	ChickinBaseDTO
	ProjectFlockKandang *ProjectFlockKandangDTO  `json:"project_flock_kandang"`
	CreatedUser         *userBaseDTO.UserBaseDTO `json:"created_user"`
	CreatedAt           time.Time                `json:"created_at"`
	UpdatedAt           time.Time                `json:"updated_at"`
}

type ChickinDetailDTO struct {
	ChickinListDTO
}

// === Mapper Functions (ordered) ===

func ToFlockDTO(e entity.Flock) flockBaseDTO.FlockBaseDTO {
	return flockBaseDTO.ToFlockBaseDTO(e)
}

func ToKandangDTO(e entity.Kandang) kandangBaseDTO.KandangBaseDTO {
	return kandangBaseDTO.ToKandangBaseDTO(e)
}
func ToAreaDTO(e entity.Area) areaBaseDTO.AreaBaseDTO {
	return areaBaseDTO.ToAreaBaseDTO(e)
}

func ToFcrDTO(e entity.Fcr) fcrBaseDTO.FcrBaseDTO {
	return fcrBaseDTO.ToFcrBaseDTO(e)
}

func ToLocationDTO(e entity.Location) locationBaseDTO.LocationBaseDTO {
	return locationBaseDTO.ToLocationBaseDTO(e)
}

func ToUserBaseDTO(e entity.User) userBaseDTO.UserBaseDTO {
	return userBaseDTO.ToUserBaseDTO(e)
}

func ToProjectFlockDTO(e entity.ProjectFlock) ProjectFlockDTO {
	var flock *flockBaseDTO.FlockBaseDTO
	if e.Flock.Id != 0 {
		mapped := flockBaseDTO.ToFlockBaseDTO(e.Flock)
		flock = &mapped
	}
	var area *areaBaseDTO.AreaBaseDTO
	if e.Area.Id != 0 {
		mapped := areaBaseDTO.ToAreaBaseDTO(e.Area)
		area = &mapped
	}
	var fcr *fcrBaseDTO.FcrBaseDTO
	if e.Fcr.Id != 0 {
		mapped := fcrBaseDTO.ToFcrBaseDTO(e.Fcr)
		fcr = &mapped
	}
	var location *locationBaseDTO.LocationBaseDTO
	if e.Location.Id != 0 {
		mapped := locationBaseDTO.ToLocationBaseDTO(e.Location)
		location = &mapped
	}
	return ProjectFlockDTO{
		Id:       e.Id,
		Period:   e.Period,
		Category: e.Category,
		Flock:    flock,
		Area:     area,
		Fcr:      fcr,
		Location: location,
	}
}

func ToProjectFlockKandangDTO(e entity.ProjectFlockKandang) ProjectFlockKandangDTO {
	var pf *ProjectFlockDTO
	if e.ProjectFlock.Id != 0 {
		mapped := ToProjectFlockDTO(e.ProjectFlock)
		pf = &mapped
	}
	var kandang *kandangBaseDTO.KandangBaseDTO
	if e.Kandang.Id != 0 {
		mapped := kandangBaseDTO.ToKandangBaseDTO(e.Kandang)
		kandang = &mapped
	}
	return ProjectFlockKandangDTO{
		Id:           e.Id,
		ProjectFlock: pf,
		Kandang:      kandang,
	}
}

func ToChickinBaseDTO(e entity.ProjectChickin) ChickinBaseDTO {
	var pfk *ProjectFlockKandangDTO
	if e.ProjectFlockKandang.Id != 0 {
		mapped := ToProjectFlockKandangDTO(e.ProjectFlockKandang)
		pfk = &mapped
	}
	return ChickinBaseDTO{
		Id:                  e.Id,
		ProjectFlockKandang: pfk,
		ChickInDate:         e.ChickInDate,
		Quantity:            e.Quantity,
		Note:                e.Note,
	}
}

func ToChickinSimpleDTO(e entity.ProjectChickin) ChickinSimpleDTO {
	return ChickinSimpleDTO{
		Id:                    e.Id,
		ProjectFlockKandangId: e.ProjectFlockKandangId,
		ChickInDate:           e.ChickInDate,
		Quantity:              e.Quantity,
		Note:                  e.Note,
		CreatedBy:             e.CreatedBy,
	}
}

func ToChickinListDTO(e entity.ProjectChickin) ChickinListDTO {
	var createdUser *userBaseDTO.UserBaseDTO
	if e.CreatedUser.Id != 0 {
		mapped := userBaseDTO.ToUserBaseDTO(e.CreatedUser)
		createdUser = &mapped
	}
	var pfk *ProjectFlockKandangDTO
	if e.ProjectFlockKandang.Id != 0 {
		mapped := ToProjectFlockKandangDTO(e.ProjectFlockKandang)
		pfk = &mapped
	}
	return ChickinListDTO{
		ChickinBaseDTO:      ToChickinBaseDTO(e),
		ProjectFlockKandang: pfk,
		CreatedUser:         createdUser,
		CreatedAt:           e.CreatedAt,
		UpdatedAt:           e.UpdatedAt,
	}
}

func ToChickinListDTOs(e []entity.ProjectChickin) []ChickinListDTO {
	result := make([]ChickinListDTO, len(e))
	for i, r := range e {
		result[i] = ToChickinListDTO(r)
	}
	return result
}

func ToChickinSimpleDTOs(e []entity.ProjectChickin) []ChickinSimpleDTO {
	result := make([]ChickinSimpleDTO, len(e))
	for i, r := range e {
		result[i] = ToChickinSimpleDTO(r)
	}
	return result
}

func ToChickinDetailDTO(e entity.ProjectChickin) ChickinDetailDTO {
	return ChickinDetailDTO{
		ChickinListDTO: ToChickinListDTO(e),
	}
}
