package request

import (
	"netidhub-saas-be/app/database/entity"
	"netidhub-saas-be/utils/paginator"
	"strconv"
	"time"
)

type ApprovalWorkflowsGeneric interface {
	ToEntity()
}

type ApprovalWorkflowsQueryRequest struct {
	Name        *string               `json:"name"`
	Description *string               `json:"description"`
	IsActive    *bool                 `json:"isActive"`
	IsDefault   *bool                 `json:"isDefault"`
	Pagination  *paginator.Pagination `json:"pagination"`
}

type ApprovalWorkflowsCreateRequest struct {
	Name             string                        `json:"name" validate:"required"`
	Description      string                        `json:"description" validate:"required"`
	IsActive         *bool                         `json:"isActive"`
	IsDefault        *bool                         `json:"isDefault"`
	RequiresApproval *bool                         `json:"requiresApproval"`
	AutoPublish      *bool                         `json:"autoPublish"`
	Steps            []ApprovalWorkflowStepRequest `json:"steps"`
}

func (req ApprovalWorkflowsCreateRequest) ToEntity() *entity.ApprovalWorkflows {
	return &entity.ApprovalWorkflows{
		Name:             req.Name,
		Description:      &req.Description,
		IsActive:         req.IsActive,
		IsDefault:        req.IsDefault,
		RequiresApproval: req.RequiresApproval,
		AutoPublish:      req.AutoPublish,
		CreatedAt:        time.Now(),
		UpdatedAt:        time.Now(),
	}
}

func (req ApprovalWorkflowsCreateRequest) ToStepsEntity() []*entity.ApprovalWorkflowSteps {
	steps := make([]*entity.ApprovalWorkflowSteps, len(req.Steps))
	for i, stepReq := range req.Steps {
		steps[i] = &entity.ApprovalWorkflowSteps{
			StepOrder:             stepReq.StepOrder,
			StepName:              stepReq.StepName,
			RequiredUserLevelId:   stepReq.RequiredUserLevelId,
			CanSkip:               stepReq.CanSkip,
			AutoApproveAfterHours: stepReq.AutoApproveAfterHours,
			IsActive:              stepReq.IsActive,
			CreatedAt:             time.Now(),
			UpdatedAt:             time.Now(),
		}
	}
	return steps
}

type ApprovalWorkflowsUpdateRequest struct {
	Name             string `json:"name" validate:"required"`
	Description      string `json:"description" validate:"required"`
	IsActive         *bool  `json:"isActive"`
	IsDefault        *bool  `json:"isDefault"`
	RequiresApproval *bool  `json:"requiresApproval"`
	AutoPublish      *bool  `json:"autoPublish"`
}

func (req ApprovalWorkflowsUpdateRequest) ToEntity() *entity.ApprovalWorkflows {
	return &entity.ApprovalWorkflows{
		Name:             req.Name,
		Description:      &req.Description,
		IsActive:         req.IsActive,
		IsDefault:        req.IsDefault,
		RequiresApproval: req.RequiresApproval,
		AutoPublish:      req.AutoPublish,
		UpdatedAt:        time.Now(),
	}
}

type ApprovalWorkflowStepRequest struct {
	StepOrder             int    `json:"stepOrder" validate:"required"`
	StepName              string `json:"stepName" validate:"required"`
	RequiredUserLevelId   uint   `json:"requiredUserLevelId" validate:"required"`
	CanSkip               *bool  `json:"canSkip"`
	AutoApproveAfterHours *int   `json:"autoApproveAfterHours"`
	IsActive              *bool  `json:"isActive"`

	// Multi-branch support fields
	ParentStepId   *uint   `json:"parentStepId"`
	ConditionType  *string `json:"conditionType"`  // 'user_level', 'user_level_hierarchy', 'always', 'custom'
	ConditionValue *string `json:"conditionValue"` // JSON string for conditions
	IsParallel     *bool   `json:"isParallel"`
	BranchName     *string `json:"branchName"`
	BranchOrder    *int    `json:"branchOrder"`
}

func (req ApprovalWorkflowStepRequest) ToEntity(workflowId uint) *entity.ApprovalWorkflowSteps {
	return &entity.ApprovalWorkflowSteps{
		WorkflowId:            workflowId,
		StepOrder:             req.StepOrder,
		StepName:              req.StepName,
		RequiredUserLevelId:   req.RequiredUserLevelId,
		CanSkip:               req.CanSkip,
		AutoApproveAfterHours: req.AutoApproveAfterHours,
		IsActive:              req.IsActive,

		// Multi-branch support fields
		ParentStepId:   req.ParentStepId,
		ConditionType:  req.ConditionType,
		ConditionValue: req.ConditionValue,
		IsParallel:     req.IsParallel,
		BranchName:     req.BranchName,
		BranchOrder:    req.BranchOrder,

		CreatedAt: time.Now(),
		UpdatedAt: time.Now(),
	}
}

type ApprovalWorkflowsWithStepsCreateRequest struct {
	Name             string                        `json:"name" validate:"required"`
	Description      string                        `json:"description" validate:"required"`
	IsActive         *bool                         `json:"isActive"`
	IsDefault        *bool                         `json:"isDefault"`
	RequiresApproval *bool                         `json:"requiresApproval"`
	AutoPublish      *bool                         `json:"autoPublish"`
	Steps            []ApprovalWorkflowStepRequest `json:"steps" validate:"required,min=1"`
}

func (req ApprovalWorkflowsWithStepsCreateRequest) ToEntity() *entity.ApprovalWorkflows {
	return &entity.ApprovalWorkflows{
		Name:             req.Name,
		Description:      &req.Description,
		IsActive:         req.IsActive,
		IsDefault:        req.IsDefault,
		RequiresApproval: req.RequiresApproval,
		AutoPublish:      req.AutoPublish,
		CreatedAt:        time.Now(),
		UpdatedAt:        time.Now(),
	}
}

func (req ApprovalWorkflowsWithStepsCreateRequest) ToStepsEntity() []*entity.ApprovalWorkflowSteps {
	steps := make([]*entity.ApprovalWorkflowSteps, len(req.Steps))
	for i, stepReq := range req.Steps {
		steps[i] = &entity.ApprovalWorkflowSteps{
			StepOrder:             stepReq.StepOrder,
			StepName:              stepReq.StepName,
			RequiredUserLevelId:   stepReq.RequiredUserLevelId,
			CanSkip:               stepReq.CanSkip,
			AutoApproveAfterHours: stepReq.AutoApproveAfterHours,
			IsActive:              stepReq.IsActive,

			// Multi-branch support fields
			ParentStepId:   stepReq.ParentStepId,
			ConditionType:  stepReq.ConditionType,
			ConditionValue: stepReq.ConditionValue,
			IsParallel:     stepReq.IsParallel,
			BranchName:     stepReq.BranchName,
			BranchOrder:    stepReq.BranchOrder,

			CreatedAt: time.Now(),
			UpdatedAt: time.Now(),
		}
	}
	return steps
}

type ApprovalWorkflowsWithStepsUpdateRequest struct {
	Name             string                        `json:"name" validate:"required"`
	Description      string                        `json:"description" validate:"required"`
	IsActive         *bool                         `json:"isActive"`
	IsDefault        *bool                         `json:"isDefault"`
	RequiresApproval *bool                         `json:"requiresApproval"`
	AutoPublish      *bool                         `json:"autoPublish"`
	Steps            []ApprovalWorkflowStepRequest `json:"steps" validate:"required,min=1"`
}

type ApprovalWorkflowsQueryRequestContext struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	IsActive    string `json:"isActive"`
	IsDefault   string `json:"isDefault"`
}

func (req ApprovalWorkflowsQueryRequestContext) ToParamRequest() ApprovalWorkflowsQueryRequest {
	var name *string
	var description *string
	var isActive *bool
	var isDefault *bool

	if req.Name != "" {
		name = &req.Name
	}

	if req.Description != "" {
		description = &req.Description
	}

	if req.IsActive != "" {
		if parsedIsActive, err := strconv.ParseBool(req.IsActive); err == nil {
			isActive = &parsedIsActive
		}
	}

	if req.IsDefault != "" {
		if parsedIsDefault, err := strconv.ParseBool(req.IsDefault); err == nil {
			isDefault = &parsedIsDefault
		}
	}

	return ApprovalWorkflowsQueryRequest{
		Name:        name,
		Description: description,
		IsActive:    isActive,
		IsDefault:   isDefault,
	}
}
