package com.ikon.projectmanagement.mapper;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;

import org.springframework.stereotype.Component;

import com.ikon.projectmanagement.dto.request.ProductOfProjectRequestDto;
import com.ikon.projectmanagement.dto.response.ProductExpenseResponseDto;
import com.ikon.projectmanagement.dto.response.ProductOfProjectResponseDto;
import com.ikon.projectmanagement.dto.response.ProductPSResourceAllocationResponseDto;
import com.ikon.projectmanagement.entity.ProductOfProject;
import com.ikon.projectmanagement.entity.ProductOfProjectExpenseDetail;
import com.ikon.projectmanagement.entity.ProductPSResourceAllocation;

@Component
public class ProductOfProjectMapper {

    public ProductOfProject toEntity(ProductOfProjectRequestDto dto) {
        if (dto == null)
            return null;

        ProductOfProject product = new ProductOfProject();

        product.setProjectIdentifier(dto.getProjectIdentifier());
        product.setProjectName(dto.getProjectName());
        product.setProjectManager(dto.getProjectManager());
        product.setAccountId(dto.getAccountId());
        product.setLeadIdentifier(dto.getLeadIdentifier());
        product.setProductStatus(dto.getProductStatus());
        product.setProjectStatus(dto.getProjectStatus());
        product.setProductType(dto.getProductType());
        product.setProductDescription(dto.getProductDescription());
        product.setDiscountPercent(dto.getDiscountPercent());

        if (dto.getExpenseDetails() != null && !dto.getExpenseDetails().isEmpty()) {

            Map<UUID, ProductOfProjectExpenseDetail> expenseMap = new HashMap<>();

            for (Entry<UUID, ProductExpenseResponseDto> entry : dto.getExpenseDetails().entrySet()) {

                UUID expenseId = entry.getKey();
                ProductExpenseResponseDto expDto = entry.getValue();

                ProductOfProjectExpenseDetail exp = toExpenseEntity(expDto);
                exp.setId(expenseId);
                exp.setProductPS(product);

                expenseMap.put(expenseId, exp);
            }

            product.setExpenseDetails(expenseMap);
        }

        return product;
    }

    public ProductOfProjectResponseDto toResponse(ProductOfProject entity) {
        if (entity == null)
            return null;

        ProductOfProjectResponseDto dto = new ProductOfProjectResponseDto();

        dto.setProductIdentifier(entity.getProductIdentifier());
        dto.setProjectIdentifier(entity.getProjectIdentifier());
        dto.setProjectName(entity.getProjectName());
        dto.setProjectManager(entity.getProjectManager());
        dto.setAccountId(entity.getAccountId());
        dto.setLeadIdentifier(entity.getLeadIdentifier());
        dto.setProductStatus(entity.getProductStatus());
        dto.setProjectStatus(entity.getProjectStatus());
        dto.setProductType(entity.getProductType());
        dto.setProductDescription(entity.getProductDescription());
        dto.setDiscountPercent(entity.getDiscountPercent());
        dto.setCreatedOn(entity.getCreatedOn());
        dto.setUpdatedOn(entity.getUpdatedOn());
        dto.setCreatedBy(entity.getCreatedBy());
        dto.setUpdatedBy(entity.getUpdatedBy());

        if (entity.getExpenseDetails() != null && !entity.getExpenseDetails().isEmpty()) {

            Map<UUID, ProductExpenseResponseDto> expenseDtos = new HashMap<>();

            for (Map.Entry<UUID, ProductOfProjectExpenseDetail> entry : entity.getExpenseDetails().entrySet()) {

                ProductOfProjectExpenseDetail exp = entry.getValue();

                ProductExpenseResponseDto expDto = new ProductExpenseResponseDto();
                expDto.setExpenseName(exp.getExpenseName());
                expDto.setLocation(exp.getLocation());
                expDto.setCurrency(exp.getCurrency());
                expDto.setCost(exp.getCost());
                expDto.setQuantity(exp.getQuantity());
                expDto.setTotalCost(exp.getTotalCost());
                expDto.setRemarks(exp.getRemarks());

                expenseDtos.put(entry.getKey(), expDto);
            }

            dto.setExpenseDetails(expenseDtos);
        }

        return dto;
    }

    public void updateEntity(ProductOfProject entity, ProductOfProjectRequestDto dto) {
        if (dto == null || entity == null)
            return;

        if (dto.getProjectIdentifier() != null)
            entity.setProjectIdentifier(dto.getProjectIdentifier());

        if (dto.getProjectName() != null)
            entity.setProjectName(dto.getProjectName());

        if (dto.getProjectManager() != null)
            entity.setProjectManager(dto.getProjectManager());

        if (dto.getLeadIdentifier() != null)
            entity.setLeadIdentifier(dto.getLeadIdentifier());

        if (dto.getProductStatus() != null)
            entity.setProductStatus(dto.getProductStatus());

        if (dto.getProjectStatus() != null)
            entity.setProjectStatus(dto.getProjectStatus());

        if (dto.getProductType() != null)
            entity.setProductType(dto.getProductType());

        if (dto.getProductDescription() != null)
            entity.setProductDescription(dto.getProductDescription());

        if (dto.getDiscountPercent() != null)
            entity.setDiscountPercent(dto.getDiscountPercent());

    }

    public ProductOfProjectExpenseDetail toExpenseEntity(ProductExpenseResponseDto expDto) {
        if (expDto == null)
            return null;

        return ProductOfProjectExpenseDetail.builder()
                .expenseName(expDto.getExpenseName())
                .location(expDto.getLocation())
                .currency(expDto.getCurrency())
                .cost(expDto.getCost())
                .quantity(expDto.getQuantity())
                .totalCost(expDto.getTotalCost())
                .remarks(expDto.getRemarks())
                .build();
    }

    public void updateExpenseEntity(ProductOfProjectExpenseDetail entity,
            ProductExpenseResponseDto expenseDto) {

        if (entity == null || expenseDto == null)
            return;

        if (expenseDto.getExpenseName() != null)
            entity.setExpenseName(expenseDto.getExpenseName());

        if (expenseDto.getLocation() != null)
            entity.setLocation(expenseDto.getLocation());

        if (expenseDto.getCurrency() != null)
            entity.setCurrency(expenseDto.getCurrency());

        if (expenseDto.getCost() != null)
            entity.setCost(expenseDto.getCost());

        if (expenseDto.getQuantity() != null)
            entity.setQuantity(expenseDto.getQuantity());

        if (expenseDto.getTotalCost() != null)
            entity.setTotalCost(expenseDto.getTotalCost());

        if (expenseDto.getRemarks() != null)
            entity.setRemarks(expenseDto.getRemarks());
    }

    private ProductPSResourceAllocationResponseDto toResourceAllocationResponseDto(ProductPSResourceAllocation allocation) {
        ProductPSResourceAllocationResponseDto dto = new ProductPSResourceAllocationResponseDto();
        dto.setId(allocation.getId());
        dto.setResourceType(allocation.getResourceType());
        dto.setRole(allocation.getRole());
        dto.setGradeId(allocation.getGradeId());
        dto.setEmployeeName(allocation.getEmployeeName());
        dto.setTaskName(allocation.getTaskName());
        dto.setResourceId(allocation.getResourceId());
        dto.setTaskId(allocation.getTaskId());
        dto.setAllocation(allocation.getAllocation());
        dto.setDetailedAllocation(allocation.getDetailedAllocation());
        return dto;
    }
}
