package mapper

import (
	"narasi-ahli-be/app/database/entity"
	"narasi-ahli-be/app/module/chat/request"
	"narasi-ahli-be/app/module/chat/response"
)

// ChatScheduleResponse - Response structure for chat schedule
type ChatScheduleResponse struct {
	ID             uint                                 `json:"id"`
	ChatSessionID  uint                                 `json:"chat_session_id"`
	Title          string                               `json:"title"`
	Description    string                               `json:"description"`
	Summary        string                               `json:"summary"`
	ScheduledAt    string                               `json:"scheduled_at"`
	Duration       int                                  `json:"duration"`
	Status         string                               `json:"status"`
	IsReminderSent bool                                 `json:"is_reminder_sent"`
	ReminderSentAt *string                              `json:"reminder_sent_at"`
	CreatedBy      uint                                 `json:"created_by"`
	CreatedAt      string                               `json:"created_at"`
	UpdatedAt      string                               `json:"updated_at"`
	ChatSession    *response.ChatSessionResponse        `json:"chat_session,omitempty"`
	Creator        *response.UserBasicInfo              `json:"creator,omitempty"`
	Files          []*response.ChatScheduleFileResponse `json:"files,omitempty"`
}

// ChatScheduleMapper - Mapper for chat schedule
type ChatScheduleMapper struct{}

// NewChatScheduleMapper - Create new chat schedule mapper
func NewChatScheduleMapper() *ChatScheduleMapper {
	return &ChatScheduleMapper{}
}

// ToResponse - Convert entity to response
func (m *ChatScheduleMapper) ToResponse(schedule *entity.ChatSchedules) *ChatScheduleResponse {
	if schedule == nil {
		return nil
	}

	scheduleResponse := &ChatScheduleResponse{
		ID:             schedule.ID,
		ChatSessionID:  schedule.ChatSessionID,
		Title:          schedule.Title,
		Description:    schedule.Description,
		Summary:        schedule.Summary,
		ScheduledAt:    schedule.ScheduledAt.Format("2006-01-02T15:04:05Z07:00"),
		Duration:       schedule.Duration,
		Status:         schedule.Status,
		IsReminderSent: schedule.IsReminderSent,
		CreatedBy:      schedule.CreatedBy,
		CreatedAt:      schedule.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
		UpdatedAt:      schedule.UpdatedAt.Format("2006-01-02T15:04:05Z07:00"),
	}

	if schedule.ReminderSentAt != nil {
		reminderSentAt := schedule.ReminderSentAt.Format("2006-01-02T15:04:05Z07:00")
		scheduleResponse.ReminderSentAt = &reminderSentAt
	}

	// Map chat session
	if schedule.ChatSession != nil {
		scheduleResponse.ChatSession = ChatSessionResponseMapper(schedule.ChatSession)
	}

	// Map creator
	if schedule.Creator != nil {
		scheduleResponse.Creator = &response.UserBasicInfo{
			ID:       schedule.Creator.ID,
			Username: schedule.Creator.Username,
			Fullname: schedule.Creator.Fullname,
			Email:    schedule.Creator.Email,
		}
	}

	// Map files
	if len(schedule.Files) > 0 {
		scheduleResponse.Files = make([]*response.ChatScheduleFileResponse, len(schedule.Files))
		for i, file := range schedule.Files {
			scheduleResponse.Files[i] = m.ToFileResponse(file)
		}
	}

	return scheduleResponse
}

// ToFileResponse - Convert file entity to response
func (m *ChatScheduleMapper) ToFileResponse(file *entity.ChatScheduleFiles) *response.ChatScheduleFileResponse {
	if file == nil {
		return nil
	}

	return &response.ChatScheduleFileResponse{
		ID:             file.ID,
		ChatScheduleID: file.ChatScheduleID,
		FileName:       file.FileName,
		OriginalName:   file.OriginalName,
		FilePath:       file.FilePath,
		FileSize:       file.FileSize,
		MimeType:       file.MimeType,
		FileType:       file.FileType,
		Description:    file.Description,
		IsRequired:     file.IsRequired,
		CreatedAt:      file.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
		UpdatedAt:      file.UpdatedAt.Format("2006-01-02T15:04:05Z07:00"),
	}
}

// ToEntity - Convert request to entity
func (m *ChatScheduleMapper) ToEntity(req request.ChatScheduleCreateRequest) *entity.ChatSchedules {
	schedule := &entity.ChatSchedules{
		Title:       req.Title,
		Description: req.Description,
		Summary:     req.Summary,
		ScheduledAt: req.ScheduledAt,
		Duration:    req.Duration,
		Status:      "scheduled",
	}

	// Handle ChatSessionID pointer
	if req.ChatSessionID != nil {
		schedule.ChatSessionID = *req.ChatSessionID
	}

	// Files will be attached separately using file IDs

	return schedule
}

// ToUpdateEntity - Convert update request to entity
func (m *ChatScheduleMapper) ToUpdateEntity(req request.ChatScheduleUpdateRequest) *entity.ChatSchedules {
	schedule := &entity.ChatSchedules{}

	if req.Title != "" {
		schedule.Title = req.Title
	}

	if req.Description != "" {
		schedule.Description = req.Description
	}

	if req.Summary != "" {
		schedule.Summary = req.Summary
	}

	if !req.ScheduledAt.IsZero() {
		schedule.ScheduledAt = req.ScheduledAt
	}

	if req.Duration > 0 {
		schedule.Duration = req.Duration
	}

	if req.Status != "" {
		schedule.Status = req.Status
	}

	// Files will be attached separately using file IDs

	return schedule
}

// ToResponseList - Convert entity list to response list
func (m *ChatScheduleMapper) ToResponseList(schedules []*entity.ChatSchedules) []*ChatScheduleResponse {
	if schedules == nil {
		return nil
	}

	responses := make([]*ChatScheduleResponse, len(schedules))
	for i, schedule := range schedules {
		responses[i] = m.ToResponse(schedule)
	}

	return responses
}
