package mapper

import (
	"time"
	"github.com/google/uuid"
	"github.com/rs/zerolog"
	"web-qudo-be/app/database/entity"
	articleApprovalStepLogsResponse "web-qudo-be/app/module/article_approval_step_logs/response"
	articleApprovalStepLogsRepository "web-qudo-be/app/module/article_approval_step_logs/repository"
	approvalWorkflowsRepository "web-qudo-be/app/module/approval_workflows/repository"
	approvalWorkflowsResponse "web-qudo-be/app/module/approval_workflows/response"
	articlesRepository "web-qudo-be/app/module/articles/repository"
	articlesResponse "web-qudo-be/app/module/articles/response"
	usersRepository "web-qudo-be/app/module/users/repository"
	res "web-qudo-be/app/module/article_approval_flows/response"
)

func ArticleApprovalFlowsResponseMapper(
	log zerolog.Logger,
	host string,
	clientId *uuid.UUID,
	articleApprovalFlowsReq *entity.ArticleApprovalFlows,
	articlesRepo articlesRepository.ArticlesRepository,
	approvalWorkflowsRepo approvalWorkflowsRepository.ApprovalWorkflowsRepository,
	articleApprovalStepLogsRepo articleApprovalStepLogsRepository.ArticleApprovalStepLogsRepository,
	usersRepo usersRepository.UsersRepository,
) (articleApprovalFlowsRes *res.ArticleApprovalFlowsResponse) {



	// Get article information
	var articleRes *articlesResponse.ArticlesResponse
	if articleApprovalFlowsReq.ArticleId != 0 {
		article, _ := articlesRepo.FindOne(clientId, articleApprovalFlowsReq.ArticleId)
		if article != nil {
			// Note: This would need additional repositories for full mapping
			// For now, we'll create a basic response
			articleRes = &articlesResponse.ArticlesResponse{
				ID:          article.ID,
				Title:       article.Title,
				Slug:        article.Slug,
				Description: article.Description,
				StatusId:    article.StatusId,
				IsActive:    article.IsActive,
				CreatedAt:   article.CreatedAt,
				UpdatedAt:   article.UpdatedAt,
			}
		}
	}

	// Get approval workflow information
	var approvalWorkflowRes *approvalWorkflowsResponse.ApprovalWorkflowsResponse
	if articleApprovalFlowsReq.WorkflowId != 0 {
		approvalWorkflow, _ := approvalWorkflowsRepo.FindOne(clientId, articleApprovalFlowsReq.WorkflowId)
		if approvalWorkflow != nil {
			// Note: This would need additional repositories for full mapping
			// For now, we'll create a basic response
			approvalWorkflowRes = &approvalWorkflowsResponse.ApprovalWorkflowsResponse{
				ID:          approvalWorkflow.ID,
				Name:        approvalWorkflow.Name,
				Description: approvalWorkflow.Description,
				IsActive:    *approvalWorkflow.IsActive,
				CreatedAt:   approvalWorkflow.CreatedAt,
				UpdatedAt:   approvalWorkflow.UpdatedAt,
			}
		}
	}

	// Get step logs
	var stepLogsArr []*articleApprovalStepLogsResponse.ArticleApprovalStepLogsResponse

	if articleApprovalFlowsReq != nil {
		// Map status ID to status string
		statusStr := "pending"
		switch articleApprovalFlowsReq.StatusId {
		case 1:
			statusStr = "pending"
		case 2:
			statusStr = "approved"
		case 3:
			statusStr = "rejected"
		case 4:
			statusStr = "revision_requested"
		}

		articleApprovalFlowsRes = &res.ArticleApprovalFlowsResponse{
			ID:                  articleApprovalFlowsReq.ID,
			ArticleID:           articleApprovalFlowsReq.ArticleId,
			WorkflowID:          articleApprovalFlowsReq.WorkflowId,
			CurrentStep:         articleApprovalFlowsReq.CurrentStep,
			Status:              statusStr,
			SubmittedBy:         articleApprovalFlowsReq.SubmittedById,
			SubmittedAt:         articleApprovalFlowsReq.SubmittedAt,
			CompletedAt:         articleApprovalFlowsReq.CompletedAt,
			RejectionReason:     articleApprovalFlowsReq.RejectionReason,
			RevisionReason:      articleApprovalFlowsReq.RevisionMessage,
			CreatedAt:           articleApprovalFlowsReq.CreatedAt,
			UpdatedAt:           articleApprovalFlowsReq.UpdatedAt,
			Article:             articleRes,
			Workflow:            approvalWorkflowRes,
			StepLogs:            stepLogsArr,
		}
	}

	return articleApprovalFlowsRes
}

func ArticleApprovalFlowsDetailResponseMapper(
	log zerolog.Logger,
	host string,
	clientId *uuid.UUID,
	articleApprovalFlowsReq *entity.ArticleApprovalFlows,
	articlesRepo articlesRepository.ArticlesRepository,
	approvalWorkflowsRepo approvalWorkflowsRepository.ApprovalWorkflowsRepository,
	articleApprovalStepLogsRepo articleApprovalStepLogsRepository.ArticleApprovalStepLogsRepository,
	usersRepo usersRepository.UsersRepository,
) (articleApprovalFlowsRes *res.ArticleApprovalFlowsDetailResponse) {

	submittedByName := ""
	if articleApprovalFlowsReq.SubmittedById != 0 {
		findUser, _ := usersRepo.FindOne(clientId, articleApprovalFlowsReq.SubmittedById)
		if findUser != nil {
			submittedByName = findUser.Fullname
		}
	}
	if articleApprovalFlowsReq.SubmittedById != 0 {
		findUser, _ := usersRepo.FindOne(clientId, articleApprovalFlowsReq.SubmittedById)
		if findUser != nil {
			submittedByName = findUser.Fullname
		}
	}

	// Get article information with full details
	var articleRes *articlesResponse.ArticlesResponse
	if articleApprovalFlowsReq.ArticleId != 0 {
		article, _ := articlesRepo.FindOne(clientId, articleApprovalFlowsReq.ArticleId)
		if article != nil {
			// Note: This would need additional repositories for full mapping
			// For now, we'll create a basic response
			articleRes = &articlesResponse.ArticlesResponse{
				ID:          article.ID,
				Title:       article.Title,
				Slug:        article.Slug,
				Description: article.Description,
				StatusId:    article.StatusId,
				IsActive:    article.IsActive,
				CreatedAt:   article.CreatedAt,
				UpdatedAt:   article.UpdatedAt,
			}
		}
	}

	// Get approval workflow information with full details
	var approvalWorkflowRes *approvalWorkflowsResponse.ApprovalWorkflowsWithStepsResponse
	if articleApprovalFlowsReq.WorkflowId != 0 {
		approvalWorkflow, _ := approvalWorkflowsRepo.FindOne(clientId, articleApprovalFlowsReq.WorkflowId)
		if approvalWorkflow != nil {
			// Note: This would need additional repositories for full mapping
			// For now, we'll create a basic response
			approvalWorkflowRes = &approvalWorkflowsResponse.ApprovalWorkflowsWithStepsResponse{
				ID:          approvalWorkflow.ID,
				Name:        approvalWorkflow.Name,
				Description: approvalWorkflow.Description,
				IsActive:    *approvalWorkflow.IsActive,
				CreatedAt:   approvalWorkflow.CreatedAt,
				UpdatedAt:   approvalWorkflow.UpdatedAt,

			}
		}
	}

	// Get step logs with detailed information
	var stepLogsArr []*articleApprovalStepLogsResponse.ArticleApprovalStepLogsResponse

	if articleApprovalFlowsReq != nil {
		// Map status ID to status string
		statusStr := "pending"
		switch articleApprovalFlowsReq.StatusId {
		case 1:
			statusStr = "pending"
		case 2:
			statusStr = "approved"
		case 3:
			statusStr = "rejected"
		case 4:
			statusStr = "revision_requested"
		}

		articleApprovalFlowsRes = &res.ArticleApprovalFlowsDetailResponse{
			ID:                  articleApprovalFlowsReq.ID,
			ArticleID:           articleApprovalFlowsReq.ArticleId,
			WorkflowID:          articleApprovalFlowsReq.WorkflowId,
			CurrentStep:         articleApprovalFlowsReq.CurrentStep,
			Status:              statusStr,
			SubmittedBy:         articleApprovalFlowsReq.SubmittedById,
			SubmittedByName:     submittedByName,
			SubmittedAt:         articleApprovalFlowsReq.SubmittedAt,
			CompletedAt:         articleApprovalFlowsReq.CompletedAt,
			RejectionReason:     articleApprovalFlowsReq.RejectionReason,
			RevisionReason:      articleApprovalFlowsReq.RevisionMessage,
			CreatedAt:           articleApprovalFlowsReq.CreatedAt,
			UpdatedAt:           articleApprovalFlowsReq.UpdatedAt,
			Article:             articleRes,
			Workflow:            approvalWorkflowRes,
			StepLogs:            stepLogsArr,
		}
	}

	return articleApprovalFlowsRes
}

func ArticleApprovalFlowsSummaryResponseMapper(
	log zerolog.Logger,
	clientId *uuid.UUID,
	articleApprovalFlowsReq *entity.ArticleApprovalFlows,
	usersRepo usersRepository.UsersRepository,
) (articleApprovalFlowsRes *res.ArticleApprovalFlowsSummaryResponse) {

	submittedByName := ""
	if articleApprovalFlowsReq.SubmittedById != 0 {
		findUser, _ := usersRepo.FindOne(clientId, articleApprovalFlowsReq.SubmittedById)
		if findUser != nil {
			submittedByName = findUser.Fullname
		}
	}

	if articleApprovalFlowsReq != nil {
		// Map status ID to status string
		statusStr := "pending"
		switch articleApprovalFlowsReq.StatusId {
		case 1:
			statusStr = "pending"
		case 2:
			statusStr = "approved"
		case 3:
			statusStr = "rejected"
		case 4:
			statusStr = "revision_requested"
		}

		// Calculate days in approval
		daysInApproval := int(time.Since(articleApprovalFlowsReq.SubmittedAt).Hours() / 24)

		articleApprovalFlowsRes = &res.ArticleApprovalFlowsSummaryResponse{
			ID:              articleApprovalFlowsReq.ID,
			ArticleID:       articleApprovalFlowsReq.ArticleId,
			CurrentStep:     articleApprovalFlowsReq.CurrentStep,
			Status:          statusStr,
			SubmittedBy:     articleApprovalFlowsReq.SubmittedById,
			SubmittedByName: submittedByName,
			SubmittedAt:     articleApprovalFlowsReq.SubmittedAt,
			DaysInApproval:  daysInApproval,
		}
	}

	return articleApprovalFlowsRes
}