package request

import (
	"strconv"
	"time"
	"web-qudo-be/app/database/entity"
	"web-qudo-be/utils/paginator"
)

type SchedulesGeneric interface {
	ToEntity()
}

type SchedulesQueryRequest struct {
	Title           *string               `json:"title"`
	Description     *string               `json:"description"`
	Location        *string               `json:"location"`
	TypeId          *int                  `json:"typeId"`
	StartDate       *time.Time            `json:"startDate"`
	EndDate         *time.Time            `json:"endDate"`
	IsLiveStreaming *bool                 `json:"isLiveStreaming"`
	Speakers        *string               `json:"speakers"`
	StatusId        *int                  `json:"statusId"`
	CreatedById     *uint                 `json:"createdById"`
	Pagination      *paginator.Pagination `json:"pagination"`
}

type SchedulesCreateRequest struct {
	Title            string     `json:"title" validate:"required"`
	Description      string     `json:"description" validate:"required"`
	Location         string     `json:"location" validate:"required"`
	IsLiveStreaming  *bool      `json:"isLiveStreaming"`
	LiveStreamingUrl *string    `json:"liveStreamingUrl"`
	TypeId           int        `json:"typeId" validate:"required"`
	StartDate        *time.Time `json:"startDate"`
	EndDate          *time.Time `json:"endDate"`
	StartTime        *string    `json:"startTime"`
	EndTime          *string    `json:"endTime"`
	Speakers         string     `json:"speakers" validate:"required"`
	PosterImagePath  *string    `json:"posterImagePath"`
	CreatedById      *uint      `json:"createdById"`
}

func (req SchedulesCreateRequest) ToEntity() *entity.Schedules {
	return &entity.Schedules{
		Title:            req.Title,
		Description:      req.Description,
		Location:         req.Location,
		IsLiveStreaming:  req.IsLiveStreaming,
		LiveStreamingUrl: req.LiveStreamingUrl,
		TypeId:           req.TypeId,
		StartDate:        req.StartDate,
		EndDate:          req.EndDate,
		StartTime:        req.StartTime,
		EndTime:          req.EndTime,
		Speakers:         req.Speakers,
		PosterImagePath:  req.PosterImagePath,
		CreatedById:      req.CreatedById,
	}
}

type SchedulesUpdateRequest struct {
	Title            string     `json:"title" validate:"required"`
	Description      string     `json:"description" validate:"required"`
	Location         string     `json:"location" validate:"required"`
	IsLiveStreaming  *bool      `json:"isLiveStreaming"`
	LiveStreamingUrl *string    `json:"liveStreamingUrl"`
	TypeId           int        `json:"typeId" validate:"required"`
	StartDate        *time.Time `json:"startDate"`
	EndDate          *time.Time `json:"endDate"`
	StartTime        *string    `json:"startTime"`
	EndTime          *string    `json:"endTime"`
	Speakers         string     `json:"speakers" validate:"required"`
	PosterImagePath  *string    `json:"posterImagePath"`
	StatusId         *int       `json:"statusId"`
}

func (req SchedulesUpdateRequest) ToEntity() *entity.Schedules {
	return &entity.Schedules{
		Title:            req.Title,
		Description:      req.Description,
		Location:         req.Location,
		IsLiveStreaming:  req.IsLiveStreaming,
		LiveStreamingUrl: req.LiveStreamingUrl,
		TypeId:           req.TypeId,
		StartDate:        req.StartDate,
		EndDate:          req.EndDate,
		StartTime:        req.StartTime,
		EndTime:          req.EndTime,
		Speakers:         req.Speakers,
		PosterImagePath:  req.PosterImagePath,
		StatusId:         req.StatusId,
		UpdatedAt:        time.Now(),
	}
}

type SchedulesQueryRequestContext struct {
	Title           string `json:"title"`
	Description     string `json:"description"`
	Location        string `json:"location"`
	TypeId          string `json:"typeId"`
	StartDate       string `json:"startDate"`
	EndDate         string `json:"endDate"`
	IsLiveStreaming string `json:"isLiveStreaming"`
	Speakers        string `json:"speakers"`
	StatusId        string `json:"statusId"`
	CreatedById     string `json:"createdById"`
}

func (req SchedulesQueryRequestContext) ToParamRequest() SchedulesQueryRequest {
	var request SchedulesQueryRequest

	if title := req.Title; title != "" {
		request.Title = &title
	}
	if description := req.Description; description != "" {
		request.Description = &description
	}
	if location := req.Location; location != "" {
		request.Location = &location
	}
	if typeIdStr := req.TypeId; typeIdStr != "" {
		typeId, err := strconv.Atoi(typeIdStr)
		if err == nil {
			request.TypeId = &typeId
		}
	}
	if startDateStr := req.StartDate; startDateStr != "" {
		if startDate, err := time.Parse("2006-01-02", startDateStr); err == nil {
			request.StartDate = &startDate
		}
	}
	if endDateStr := req.EndDate; endDateStr != "" {
		if endDate, err := time.Parse("2006-01-02", endDateStr); err == nil {
			request.EndDate = &endDate
		}
	}
	if isLiveStreamingStr := req.IsLiveStreaming; isLiveStreamingStr != "" {
		isLiveStreaming, err := strconv.ParseBool(isLiveStreamingStr)
		if err == nil {
			request.IsLiveStreaming = &isLiveStreaming
		}
	}
	if speakers := req.Speakers; speakers != "" {
		request.Speakers = &speakers
	}
	if statusIdStr := req.StatusId; statusIdStr != "" {
		statusId, err := strconv.Atoi(statusIdStr)
		if err == nil {
			request.StatusId = &statusId
		}
	}
	if createdByIdStr := req.CreatedById; createdByIdStr != "" {
		createdById, err := strconv.Atoi(createdByIdStr)
		if err == nil {
			createdByIdUint := uint(createdById)
			request.CreatedById = &createdByIdUint
		}
	}

	return request
}
