package com.social.media.mapper;

import com.social.media.domain.entity.Company;
import com.social.media.dto.CompanyDto;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class CompanyMapper {
    
    /**
     * Convert Company entity to CompanyDto
     */
    public CompanyDto toDto(Company company) {
        if (company == null) {
            return null;
        }
        
        CompanyDto dto = new CompanyDto();
        dto.setId(company.getId());
        dto.setCompanyCode(company.getCompanyCode());
        dto.setName(company.getName());
        dto.setEmail(company.getEmail());
        dto.setCnpj(company.getCnpj());
        dto.setPhone(company.getPhone());
        dto.setWebsite(company.getWebsite());
        dto.setActivitySector(company.getActivitySector());
        
        // Convert enums to strings
        dto.setPlan(company.getPlan() != null ? company.getPlan().name() : null);
        dto.setStatus(company.getStatus() != null ? company.getStatus().name() : null);
        dto.setBranchType(company.getBranchType() != null ? company.getBranchType().name() : null);
        dto.setBranchStatus(company.getBranchStatus() != null ? company.getBranchStatus().name() : null);
        
        // Hierarchy fields
        dto.setParentCompanyId(company.getParentCompanyId());
        dto.setHierarchyLevel(company.getHierarchyLevel());
        dto.setBranchCode(company.getBranchCode());
        dto.setRegion(company.getRegion());
        
        // Audit fields
        dto.setCreatedAt(company.getCreatedAt());
        dto.setUpdatedAt(company.getUpdatedAt());
        dto.setCreatedBy(company.getCreatedBy());
        dto.setUpdatedBy(company.getUpdatedBy());
        dto.setVersion(company.getVersion());
        
        // Address
        if (hasAddress(company)) {
            CompanyDto.AddressDto addressDto = new CompanyDto.AddressDto();
            addressDto.setStreet(company.getAddressStreet());
            addressDto.setNumber(company.getAddressNumber());
            addressDto.setComplement(company.getAddressComplement());
            addressDto.setNeighborhood(company.getAddressNeighborhood());
            addressDto.setCity(company.getAddressCity());
            addressDto.setState(company.getAddressState());
            addressDto.setZipCode(company.getAddressZipCode());
            addressDto.setCountry(company.getAddressCountry());
            dto.setAddress(addressDto);
        }
        
        return dto;
    }
    
    /**
     * Convert CompanyDto to Company entity
     */
    public Company toEntity(CompanyDto dto) {
        if (dto == null) {
            return null;
        }
        
        Company company = new Company();
        company.setId(dto.getId());
        company.setCompanyCode(dto.getCompanyCode());
        company.setName(dto.getName());
        company.setEmail(dto.getEmail());
        company.setCnpj(dto.getCnpj());
        company.setPhone(dto.getPhone());
        company.setWebsite(dto.getWebsite());
        company.setActivitySector(dto.getActivitySector());
        
        // Convert strings to enums with default values
        if (dto.getPlan() != null) {
            try {
                company.setPlan(Company.CompanyPlan.valueOf(dto.getPlan()));
            } catch (IllegalArgumentException e) {
                company.setPlan(Company.CompanyPlan.BASIC);
            }
        } else {
            company.setPlan(Company.CompanyPlan.BASIC);
        }
        
        if (dto.getStatus() != null) {
            try {
                company.setStatus(Company.CompanyStatus.valueOf(dto.getStatus()));
            } catch (IllegalArgumentException e) {
                company.setStatus(Company.CompanyStatus.TRIAL);
            }
        } else {
            company.setStatus(Company.CompanyStatus.TRIAL);
        }
        
        if (dto.getBranchType() != null) {
            try {
                company.setBranchType(Company.CompanyBranchType.valueOf(dto.getBranchType()));
            } catch (IllegalArgumentException e) {
                company.setBranchType(Company.CompanyBranchType.MATRIZ);
            }
        } else {
            company.setBranchType(Company.CompanyBranchType.MATRIZ);
        }
        
        if (dto.getBranchStatus() != null) {
            try {
                company.setBranchStatus(Company.CompanyBranchStatus.valueOf(dto.getBranchStatus()));
            } catch (IllegalArgumentException e) {
                company.setBranchStatus(Company.CompanyBranchStatus.ACTIVE);
            }
        } else {
            company.setBranchStatus(Company.CompanyBranchStatus.ACTIVE);
        }
        
        // Hierarchy fields
        company.setParentCompanyId(dto.getParentCompanyId());
        company.setHierarchyLevel(dto.getHierarchyLevel() != null ? dto.getHierarchyLevel() : 0);
        company.setBranchCode(dto.getBranchCode());
        company.setRegion(dto.getRegion());
        
        // Audit fields
        company.setCreatedBy(dto.getCreatedBy());
        company.setUpdatedBy(dto.getUpdatedBy());
        company.setVersion(dto.getVersion());
        
        // Address
        if (dto.getAddress() != null) {
            CompanyDto.AddressDto addressDto = dto.getAddress();
            company.setAddressStreet(addressDto.getStreet());
            company.setAddressNumber(addressDto.getNumber());
            company.setAddressComplement(addressDto.getComplement());
            company.setAddressNeighborhood(addressDto.getNeighborhood());
            company.setAddressCity(addressDto.getCity());
            company.setAddressState(addressDto.getState());
            company.setAddressZipCode(addressDto.getZipCode());
            company.setAddressCountry(addressDto.getCountry());
        }
        
        return company;
    }
    
    /**
     * Create a new Company entity from CompanyDto for creation
     */
    public Company createEntity(CompanyDto dto) {
        if (dto == null) {
            return null;
        }
        
        Company company = new Company();
        company.setName(dto.getName());
        company.setEmail(dto.getEmail());
        company.setCnpj(dto.getCnpj());
        company.setPhone(dto.getPhone());
        company.setWebsite(dto.getWebsite());
        company.setActivitySector(dto.getActivitySector());
        
        // Set default values if not provided
        if (dto.getPlan() != null) {
            try {
                company.setPlan(Company.CompanyPlan.valueOf(dto.getPlan()));
            } catch (IllegalArgumentException e) {
                company.setPlan(Company.CompanyPlan.BASIC);
            }
        } else {
            company.setPlan(Company.CompanyPlan.BASIC);
        }
        
        if (dto.getStatus() != null) {
            try {
                company.setStatus(Company.CompanyStatus.valueOf(dto.getStatus()));
            } catch (IllegalArgumentException e) {
                company.setStatus(Company.CompanyStatus.TRIAL);
            }
        } else {
            company.setStatus(Company.CompanyStatus.TRIAL);
        }
        
        if (dto.getBranchType() != null) {
            try {
                company.setBranchType(Company.CompanyBranchType.valueOf(dto.getBranchType()));
            } catch (IllegalArgumentException e) {
                company.setBranchType(Company.CompanyBranchType.MATRIZ);
            }
        } else {
            company.setBranchType(Company.CompanyBranchType.MATRIZ);
        }
        
        if (dto.getBranchStatus() != null) {
            try {
                company.setBranchStatus(Company.CompanyBranchStatus.valueOf(dto.getBranchStatus()));
            } catch (IllegalArgumentException e) {
                company.setBranchStatus(Company.CompanyBranchStatus.ACTIVE);
            }
        } else {
            company.setBranchStatus(Company.CompanyBranchStatus.ACTIVE);
        }
        
        // Hierarchy fields
        company.setParentCompanyId(dto.getParentCompanyId());
        company.setHierarchyLevel(dto.getHierarchyLevel() != null ? dto.getHierarchyLevel() : 0);
        company.setBranchCode(dto.getBranchCode());
        company.setRegion(dto.getRegion());
        
        // Audit fields
        company.setCreatedBy(dto.getCreatedBy());
        company.setUpdatedBy(dto.getUpdatedBy());
        
        // Address
        if (dto.getAddress() != null) {
            CompanyDto.AddressDto addressDto = dto.getAddress();
            company.setAddressStreet(addressDto.getStreet());
            company.setAddressNumber(addressDto.getNumber());
            company.setAddressComplement(addressDto.getComplement());
            company.setAddressNeighborhood(addressDto.getNeighborhood());
            company.setAddressCity(addressDto.getCity());
            company.setAddressState(addressDto.getState());
            company.setAddressZipCode(addressDto.getZipCode());
            company.setAddressCountry(addressDto.getCountry());
        }
        
        LocalDateTime now = LocalDateTime.now();
        company.setCreatedAt(now);
        company.setUpdatedAt(now);
        
        return company;
    }
    
    /**
     * Update existing Company entity from CompanyDto
     */
    public void updateEntity(Company existingCompany, CompanyDto dto) {
        if (existingCompany == null || dto == null) {
            return;
        }
        
        // Update basic fields
        existingCompany.setName(dto.getName());
        existingCompany.setEmail(dto.getEmail());
        existingCompany.setCnpj(dto.getCnpj());
        existingCompany.setPhone(dto.getPhone());
        existingCompany.setWebsite(dto.getWebsite());
        existingCompany.setActivitySector(dto.getActivitySector());
        
        // Update enums
        if (dto.getPlan() != null) {
            try {
                existingCompany.setPlan(Company.CompanyPlan.valueOf(dto.getPlan()));
            } catch (IllegalArgumentException e) {
                // Keep existing value if invalid
            }
        }
        
        if (dto.getStatus() != null) {
            try {
                existingCompany.setStatus(Company.CompanyStatus.valueOf(dto.getStatus()));
            } catch (IllegalArgumentException e) {
                // Keep existing value if invalid
            }
        }
        
        if (dto.getBranchType() != null) {
            try {
                existingCompany.setBranchType(Company.CompanyBranchType.valueOf(dto.getBranchType()));
            } catch (IllegalArgumentException e) {
                // Keep existing value if invalid
            }
        }
        
        if (dto.getBranchStatus() != null) {
            try {
                existingCompany.setBranchStatus(Company.CompanyBranchStatus.valueOf(dto.getBranchStatus()));
            } catch (IllegalArgumentException e) {
                // Keep existing value if invalid
            }
        }
        
        // Update hierarchy fields
        existingCompany.setParentCompanyId(dto.getParentCompanyId());
        if (dto.getHierarchyLevel() != null) {
            existingCompany.setHierarchyLevel(dto.getHierarchyLevel());
        }
        existingCompany.setBranchCode(dto.getBranchCode());
        existingCompany.setRegion(dto.getRegion());
        
        // Update audit fields
        existingCompany.setUpdatedBy(dto.getUpdatedBy());
        existingCompany.setUpdatedAt(LocalDateTime.now());
        
        // Update address
        if (dto.getAddress() != null) {
            CompanyDto.AddressDto addressDto = dto.getAddress();
            existingCompany.setAddressStreet(addressDto.getStreet());
            existingCompany.setAddressNumber(addressDto.getNumber());
            existingCompany.setAddressComplement(addressDto.getComplement());
            existingCompany.setAddressNeighborhood(addressDto.getNeighborhood());
            existingCompany.setAddressCity(addressDto.getCity());
            existingCompany.setAddressState(addressDto.getState());
            existingCompany.setAddressZipCode(addressDto.getZipCode());
            existingCompany.setAddressCountry(addressDto.getCountry());
        } else {
            // Clear address if null
            existingCompany.setAddressStreet(null);
            existingCompany.setAddressNumber(null);
            existingCompany.setAddressComplement(null);
            existingCompany.setAddressNeighborhood(null);
            existingCompany.setAddressCity(null);
            existingCompany.setAddressState(null);
            existingCompany.setAddressZipCode(null);
            existingCompany.setAddressCountry(null);
        }
    }
    
    /**
     * Convert list of Company entities to list of CompanyDto
     */
    public List<CompanyDto> toDtoList(List<Company> companies) {
        if (companies == null) {
            return null;
        }
        
        return companies.stream()
                .map(this::toDto)
                .collect(Collectors.toList());
    }
    
    /**
     * Check if company has any address information
     */
    private boolean hasAddress(Company company) {
        return company.getAddressStreet() != null ||
               company.getAddressNumber() != null ||
               company.getAddressComplement() != null ||
               company.getAddressNeighborhood() != null ||
               company.getAddressCity() != null ||
               company.getAddressState() != null ||
               company.getAddressZipCode() != null ||
               company.getAddressCountry() != null;
    }
}
