package dto

import (
	"time"

	entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
	employeeDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/employees/dto"
	kandangDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/dto"
	phaseActivityDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/phase-activities/dto"
	phasesDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/phasess/dto"
	userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
)

// === DTO Structs ===

type DailyChecklistRelationDTO struct {
	Id   uint   `json:"id"`
	Name string `json:"name"`
}

type DailyChecklistListDTO struct {
	Id            uint                                `json:"id"`
	Name          string                              `json:"name"`
	Status        string                              `json:"status"`
	Category      string                              `json:"category"`
	Date          time.Time                           `json:"date"`
	Kandang       *kandangDTO.KandangGroupRelationDTO `json:"kandang,omitempty"`
	CreatedUser   *userDTO.UserRelationDTO            `json:"created_user"`
	CreatedAt     time.Time                           `json:"created_at"`
	UpdatedAt     time.Time                           `json:"updated_at"`
	TotalPhase    int                                 `json:"total_phase"`
	TotalActivity int                                 `json:"total_activity"`
	Progress      int                                 `json:"progress"`
	RejectReason  *string                             `json:"reject_reason"`
}

type DailyChecklistDetailDTO struct {
	DailyChecklistListDTO
	Phases            []DailyChecklistPhaseDTO           `json:"phases"`
	Tasks             []DailyChecklistActivityTaskDTO    `json:"tasks"`
	AssignedEmployees []employeeDTO.EmployeesRelationDTO `json:"assigned_employees"`
	TotalActivity     int                                `json:"total_activity"`
	Progress          float64                            `json:"progress"`
	DocumentURLs      []DailyChecklistDocumentDTO        `json:"document_urls"`
}

type DailyChecklistDocumentDTO struct {
	Id   uint    `json:"id"`
	Name string  `json:"name"`
	Size float64 `json:"size"`
	URL  string  `json:"url"`
}

type DailyChecklistSummaryDTO struct {
	EmployeeID     uint       `json:"employee_id"`
	EmployeeName   string     `json:"employee_name"`
	KandangID      uint       `json:"kandang_id"`
	KandangName    string     `json:"kandang_name"`
	TotalActivity  int        `json:"total_activity"`
	ActivityDone   int        `json:"activity_done"`
	ActivityLeft   int        `json:"activity_left"`
	CompletionRate int        `json:"completion_rate"`
	LastActivity   *time.Time `json:"last_activity,omitempty"`
}

type DailyChecklistPerformanceOverviewDTO struct {
	EmployeeID    uint                          `json:"employee_id"`
	EmployeeName  string                        `json:"employee_name"`
	Kandang       DailyChecklistReportEntityDTO `json:"kandang"`
	TotalActivity int                           `json:"total_activity"`
	ActivityDone  int                           `json:"activity_done"`
	ActivityLeft  int                           `json:"activity_left"`
}

type DailyChecklistReportDTO struct {
	Area            DailyChecklistReportEntityDTO  `json:"area"`
	Farm            DailyChecklistReportEntityDTO  `json:"farm"`
	Kandang         DailyChecklistReportEntityDTO  `json:"kandang"`
	ABK             DailyChecklistReportEntityDTO  `json:"abk"`
	Phase           string                         `json:"phase"`
	DailyActivities map[string]int                 `json:"daily_activities"`
	Summary         DailyChecklistReportSummaryDTO `json:"summary"`
}

type DailyChecklistReportEntityDTO struct {
	Id   uint   `json:"id"`
	Name string `json:"name"`
}

type DailyChecklistReportSummaryDTO struct {
	TotalChecklist    int                             `json:"total_checklist"`
	JumlahHariEfektif int                             `json:"jumlah_hari_efektif"`
	AbkPercentage     int                             `json:"abk_percentage"`
	KandangPercentage int                             `json:"kandang_percentage"`
	Kategori          DailyChecklistReportCategoryDTO `json:"kategori"`
}

type DailyChecklistReportCategoryDTO struct {
	Kurang int `json:"kurang"`
	Cukup  int `json:"cukup"`
	Baik   int `json:"baik"`
}

type DailyChecklistPhaseDTO struct {
	Id      uint                    `json:"id"`
	PhaseId uint                    `json:"phase_id"`
	Phase   phasesDTO.PhasesListDTO `json:"phase"`
}

type DailyChecklistActivityTaskDTO struct {
	Id              uint                                  `json:"id"`
	ChecklistId     uint                                  `json:"checklist_id"`
	PhaseId         uint                                  `json:"phase_id"`
	PhaseActivityId uint                                  `json:"phase_activity_id"`
	TimeType        *string                               `json:"time_type"`
	Notes           *string                               `json:"notes"`
	Phase           phasesDTO.PhasesListDTO               `json:"phase"`
	PhaseActivity   phaseActivityDTO.PhaseActivityListDTO `json:"phase_activity"`
	Assignments     []DailyChecklistAssignmentDTO         `json:"assignments"`
}

type DailyChecklistAssignmentDTO struct {
	Employee employeeDTO.EmployeesRelationDTO `json:"employee"`
	Checked  bool                             `json:"checked"`
	Note     *string                          `json:"note"`
}

// === Mapper Functions ===

func ToDailyChecklistRelationDTO(e entity.DailyChecklist) DailyChecklistRelationDTO {
	var name string
	if e.Name != nil {
		name = *e.Name
	}

	return DailyChecklistRelationDTO{
		Id:   e.Id,
		Name: name,
	}
}

func ToDailyChecklistListDTO(e entity.DailyChecklist) DailyChecklistListDTO {
	var createdUser *userDTO.UserRelationDTO
	// if e.CreatedUser.Id != 0 {
	// 	mapped := userDTO.ToUserRelationDTO(e.CreatedUser)
	// 	createdUser = &mapped
	// }

	var name string
	if e.Name != nil {
		name = *e.Name
	}

	var status string
	if e.Status != nil {
		status = *e.Status
	}

	var kandang *kandangDTO.KandangGroupRelationDTO
	if e.Kandang.Id != 0 {
		mapped := kandangDTO.ToKandangGroupRelationDTO(e.Kandang)
		kandang = &mapped
	}

	return DailyChecklistListDTO{
		Id:            e.Id,
		Name:          name,
		Status:        status,
		Category:      e.Category,
		Date:          e.Date,
		Kandang:       kandang,
		CreatedAt:     e.CreatedAt,
		UpdatedAt:     e.UpdatedAt,
		CreatedUser:   createdUser,
		TotalPhase:    0,
		TotalActivity: 0,
		Progress:      0,
		RejectReason:  e.RejectReason,
	}
}

func ToDailyChecklistDetailDTO(checklist entity.DailyChecklist, phases []entity.DailyChecklistPhase, tasks []entity.DailyChecklistActivityTask, assignedEmployees []entity.Employee, totalActivities int, progress float64, documentURLs []DailyChecklistDocumentDTO) DailyChecklistDetailDTO {
	phaseDTOs := make([]DailyChecklistPhaseDTO, 0, len(phases))
	for _, phase := range phases {
		phaseDTOs = append(phaseDTOs, DailyChecklistPhaseDTO{
			Id:      phase.Id,
			PhaseId: phase.PhaseId,
			Phase:   phasesDTO.ToPhasesListDTO(phase.Phase),
		})
	}

	taskDTOs := make([]DailyChecklistActivityTaskDTO, 0, len(tasks))
	for _, task := range tasks {
		mappedAssignments := make([]DailyChecklistAssignmentDTO, 0, len(task.Assignments))
		for _, assignment := range task.Assignments {
			if assignment.Employee.Id == 0 {
				continue
			}
			mapped := DailyChecklistAssignmentDTO{
				Employee: employeeDTO.ToEmployeesRelationDTO(assignment.Employee),
				Checked:  assignment.Checked,
				Note:     assignment.Note,
			}
			mappedAssignments = append(mappedAssignments, mapped)
		}

		phaseDTO := phasesDTO.PhasesListDTO{}
		if task.Phase.Id != 0 {
			phaseDTO = phasesDTO.ToPhasesListDTO(task.Phase)
		}

		activityDTO := phaseActivityDTO.PhaseActivityListDTO{}
		if task.PhaseActivity.Id != 0 {
			activityDTO = phaseActivityDTO.ToPhaseActivityListDTO(task.PhaseActivity)
		}

		taskDTOs = append(taskDTOs, DailyChecklistActivityTaskDTO{
			Id:              task.Id,
			ChecklistId:     task.ChecklistId,
			PhaseId:         task.PhaseId,
			PhaseActivityId: task.PhaseActivityId,
			TimeType:        task.TimeType,
			Notes:           task.Notes,
			Phase:           phaseDTO,
			PhaseActivity:   activityDTO,
			Assignments:     mappedAssignments,
		})
	}

	assignedDTOs := make([]employeeDTO.EmployeesRelationDTO, 0, len(assignedEmployees))
	for _, emp := range assignedEmployees {
		assignedDTOs = append(assignedDTOs, employeeDTO.ToEmployeesRelationDTO(emp))
	}

	return DailyChecklistDetailDTO{
		DailyChecklistListDTO: ToDailyChecklistListDTO(checklist),
		Phases:                phaseDTOs,
		Tasks:                 taskDTOs,
		AssignedEmployees:     assignedDTOs,
		TotalActivity:         totalActivities,
		Progress:              progress,
		DocumentURLs:          documentURLs,
	}
}
