package request

import (
	"narasi-ahli-be/app/database/entity"
	"narasi-ahli-be/utils/paginator"
	"strconv"
	"time"
)

type EbooksGeneric interface {
	ToEntity()
}

type EbooksQueryRequest struct {
	Title       *string               `json:"title"`
	Description *string               `json:"description"`
	AuthorId    *uint                 `json:"authorId"`
	Category    *string               `json:"category"`
	Tags        *string               `json:"tags"`
	MinPrice    *float64              `json:"minPrice"`
	MaxPrice    *float64              `json:"maxPrice"`
	StatusId    *int                  `json:"statusId"`
	IsPublished *bool                 `json:"isPublished"`
	Pagination  *paginator.Pagination `json:"pagination"`
}

type EbooksCreateRequest struct {
	Title         string  `json:"title" validate:"required"`
	Slug          string  `json:"slug" validate:"required"`
	Description   string  `json:"description" validate:"required"`
	Price         float64 `json:"price" validate:"required,min=0"`
	Category      *string `json:"category"`
	Tags          *string `json:"tags"`
	PageCount     *int    `json:"pageCount"`
	Language      *string `json:"language"`
	Isbn          *string `json:"isbn"`
	Publisher     *string `json:"publisher"`
	PublishedYear *int    `json:"publishedYear"`
	IsPublished   *bool   `json:"isPublished"`
	CreatedAt     *string `json:"createdAt"`
	CreatedById   *uint   `json:"createdById"`
}

func (req EbooksCreateRequest) ToEntity() *entity.Ebooks {
	return &entity.Ebooks{
		Title:         req.Title,
		Slug:          req.Slug,
		Description:   req.Description,
		Price:         req.Price,
		Category:      req.Category,
		Tags:          req.Tags,
		PageCount:     req.PageCount,
		Language:      req.Language,
		Isbn:          req.Isbn,
		Publisher:     req.Publisher,
		PublishedYear: req.PublishedYear,
		IsPublished:   req.IsPublished,
	}
}

type EbooksUpdateRequest struct {
	Title         string  `json:"title" validate:"required"`
	Slug          string  `json:"slug" validate:"required"`
	Description   string  `json:"description" validate:"required"`
	Price         float64 `json:"price" validate:"required,min=0"`
	Category      *string `json:"category"`
	Tags          *string `json:"tags"`
	PageCount     *int    `json:"pageCount"`
	Language      *string `json:"language"`
	Isbn          *string `json:"isbn"`
	Publisher     *string `json:"publisher"`
	PublishedYear *int    `json:"publishedYear"`
	IsPublished   *bool   `json:"isPublished"`
	StatusId      *int    `json:"statusId"`
	CreatedAt     *string `json:"createdAt"`
	CreatedById   *uint   `json:"createdById"`
}

func (req EbooksUpdateRequest) ToEntity() *entity.Ebooks {
	if req.CreatedById == nil {
		return &entity.Ebooks{
			Title:         req.Title,
			Slug:          req.Slug,
			Description:   req.Description,
			Price:         req.Price,
			Category:      req.Category,
			Tags:          req.Tags,
			PageCount:     req.PageCount,
			Language:      req.Language,
			Isbn:          req.Isbn,
			Publisher:     req.Publisher,
			PublishedYear: req.PublishedYear,
			IsPublished:   req.IsPublished,
			StatusId:      req.StatusId,
			UpdatedAt:     time.Now(),
		}
	} else {
		return &entity.Ebooks{
			Title:         req.Title,
			Slug:          req.Slug,
			Description:   req.Description,
			Price:         req.Price,
			Category:      req.Category,
			Tags:          req.Tags,
			PageCount:     req.PageCount,
			Language:      req.Language,
			Isbn:          req.Isbn,
			Publisher:     req.Publisher,
			PublishedYear: req.PublishedYear,
			IsPublished:   req.IsPublished,
			StatusId:      req.StatusId,
			CreatedById:   req.CreatedById,
			UpdatedAt:     time.Now(),
		}
	}
}

type EbooksQueryRequestContext struct {
	Title       string `json:"title"`
	Description string `json:"description"`
	AuthorId    string `json:"authorId"`
	Category    string `json:"category"`
	Tags        string `json:"tags"`
	MinPrice    string `json:"minPrice"`
	MaxPrice    string `json:"maxPrice"`
	StatusId    string `json:"statusId"`
	IsPublished string `json:"isPublished"`
}

func (req EbooksQueryRequestContext) ToParamRequest() EbooksQueryRequest {
	var request EbooksQueryRequest

	if title := req.Title; title != "" {
		request.Title = &title
	}
	if description := req.Description; description != "" {
		request.Description = &description
	}
	if category := req.Category; category != "" {
		request.Category = &category
	}
	if tags := req.Tags; tags != "" {
		request.Tags = &tags
	}
	if authorIdStr := req.AuthorId; authorIdStr != "" {
		authorId, err := strconv.Atoi(authorIdStr)
		if err == nil {
			authorIdUint := uint(authorId)
			request.AuthorId = &authorIdUint
		}
	}
	if minPriceStr := req.MinPrice; minPriceStr != "" {
		minPrice, err := strconv.ParseFloat(minPriceStr, 64)
		if err == nil {
			request.MinPrice = &minPrice
		}
	}
	if maxPriceStr := req.MaxPrice; maxPriceStr != "" {
		maxPrice, err := strconv.ParseFloat(maxPriceStr, 64)
		if err == nil {
			request.MaxPrice = &maxPrice
		}
	}
	if isPublishedStr := req.IsPublished; isPublishedStr != "" {
		isPublished, err := strconv.ParseBool(isPublishedStr)
		if err == nil {
			request.IsPublished = &isPublished
		}
	}
	if statusIdStr := req.StatusId; statusIdStr != "" {
		statusId, err := strconv.Atoi(statusIdStr)
		if err == nil {
			request.StatusId = &statusId
		}
	}

	return request
}
