package dto

import (
	"strings"
	"time"

	entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
	approvalDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/approvals/dto"
	bankDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/banks/dto"
	userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
	"gitlab.com/mbugroup/lti-api.git/internal/utils"
)

// === DTO Structs ===

type InjectionRelationDTO struct {
	Id              uint                    `json:"id"`
	TransactionType string                  `json:"transaction_type"`
	Bank            bankDTO.BankRelationDTO `json:"bank,omitempty"`
	AdjustmentDate  string                  `json:"adjustment_date"`
	Direction       string                  `json:"direction"`
	Nominal         float64                 `json:"nominal"`
	Notes           string                  `json:"notes"`
}

type InjectionListDTO struct {
	InjectionRelationDTO
	CreatedBy     uint                            `json:"created_by"`
	CreatedByUser userDTO.UserRelationDTO         `json:"created_by_user,omitempty"`
	CreatedAt     time.Time                       `json:"created_at"`
	UpdatedAt     time.Time                       `json:"updated_at"`
	Approval      approvalDTO.ApprovalRelationDTO `json:"approval"`
}

type InjectionDetailDTO struct {
	InjectionListDTO
}

// === Mapper Functions ===

func ToInjectionRelationDTO(e entity.Payment) InjectionRelationDTO {
	return InjectionRelationDTO{
		Id:              e.Id,
		TransactionType: transactionTypeLabel(e.TransactionType),
		Bank:            bankFromInjection(e),
		AdjustmentDate:  utils.FormatDate(e.PaymentDate),
		Direction:       e.Direction,
		Nominal:         e.Nominal,
		Notes:           e.Notes,
	}
}

func ToInjectionListDTO(e entity.Payment) InjectionListDTO {
	approval := approvalDTO.ApprovalRelationDTO{}
	if e.LatestApproval != nil {
		approval = approvalDTO.ToApprovalDTO(*e.LatestApproval)
	}

	return InjectionListDTO{
		InjectionRelationDTO: ToInjectionRelationDTO(e),
		CreatedBy:            e.CreatedBy,
		CreatedByUser:        userFromInjection(e),
		CreatedAt:            e.CreatedAt,
		UpdatedAt:            e.UpdatedAt,
		Approval:             approval,
	}
}

func ToInjectionListDTOs(e []entity.Payment) []InjectionListDTO {
	result := make([]InjectionListDTO, len(e))
	for i, r := range e {
		result[i] = ToInjectionListDTO(r)
	}
	return result
}

func ToInjectionDetailDTO(e entity.Payment) InjectionDetailDTO {
	return InjectionDetailDTO{
		InjectionListDTO: ToInjectionListDTO(e),
	}
}

func bankFromInjection(e entity.Payment) bankDTO.BankRelationDTO {
	if e.BankWarehouse.Id == 0 {
		return bankDTO.BankRelationDTO{}
	}
	return bankDTO.ToBankRelationDTO(e.BankWarehouse)
}

func userFromInjection(e entity.Payment) userDTO.UserRelationDTO {
	if e.CreatedUser.Id == 0 {
		return userDTO.UserRelationDTO{}
	}
	return userDTO.ToUserRelationDTO(e.CreatedUser)
}

func transactionTypeLabel(transactionType string) string {
	if strings.EqualFold(transactionType, string(utils.TransactionTypeInjection)) {
		return "Injection"
	}
	return transactionType
}
