package com.social.media.application.company.handler;

import com.social.media.application.company.command.UpdateCompanyCommand;
import com.social.media.application.company.dto.CompanyResponseDto;
import com.social.media.domain.company.aggregate.Company;
import com.social.media.domain.company.repository.CompanyRepository;
import com.social.media.domain.company.valueobject.Address;
import com.social.media.domain.company.valueobject.CompanyId;
import com.social.media.domain.company.valueobject.CompanyStatus;
import com.social.media.domain.shared.valueobject.Email;
import com.social.media.domain.shared.valueobject.Phone;
import com.social.media.domain.shared.exception.BusinessRuleViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;

/**
 * Handler for UpdateCompanyCommand
 */
@Service
@Transactional
public class UpdateCompanyCommandHandler {
    
    private final CompanyRepository companyRepository;
    
    public UpdateCompanyCommandHandler(CompanyRepository companyRepository) {
        this.companyRepository = companyRepository;
    }
    
    public CompanyResponseDto handle(UpdateCompanyCommand command) {
        // Convert UUID back to CompanyId (Long)
        CompanyId companyId = CompanyId.of(command.companyId().getMostSignificantBits());
        Company company = companyRepository.findById(companyId)
            .orElseThrow(() -> new BusinessRuleViolationException("Company not found with ID: " + command.companyId()));
        
        // Update basic information using available methods
        if (command.email() != null || command.phoneNumber() != null || command.website() != null) {
            Email email = command.email() != null ? new Email(command.email()) : company.getEmail();
            Phone phone = command.phoneNumber() != null ? new Phone(command.phoneNumber()) : company.getPhone();
            String website = command.website() != null ? command.website() : company.getWebsite();
            
            company.updateContactInfo(phone, email, website);
        }
        
        // Update address if any address field is provided
        if (command.street() != null || command.city() != null || command.state() != null) {
            Address currentAddress = company.getAddress();
            Address newAddress = new Address(
                command.street() != null ? command.street() : (currentAddress != null ? currentAddress.street() : null),
                command.number() != null ? command.number() : (currentAddress != null ? currentAddress.number() : null),
                command.complement() != null ? command.complement() : (currentAddress != null ? currentAddress.complement() : null),
                command.neighborhood() != null ? command.neighborhood() : (currentAddress != null ? currentAddress.neighborhood() : null),
                command.city() != null ? command.city() : (currentAddress != null ? currentAddress.city() : null),
                command.state() != null ? command.state() : (currentAddress != null ? currentAddress.state() : null),
                command.country() != null ? command.country() : (currentAddress != null ? currentAddress.country() : "Brasil"),
                command.postalCode() != null ? command.postalCode() : (currentAddress != null ? currentAddress.zipCode() : null)
            );
            company.setAddress(newAddress);
        }
        
        Company updatedCompany = companyRepository.save(company);
        
        return mapToDto(updatedCompany);
    }
    
    private CompanyResponseDto mapToDto(Company company) {
        return CompanyResponseDto.builder()
            .id(company.getId().value().toString())
            .name(company.getName())
            .email(company.getEmail().value())
            .website(company.getWebsite())
            .description(company.getActivitySector())
            .phone(company.getPhone() != null ? company.getPhone().value() : null)
            .address(company.getAddress() != null ? company.getAddress().street() : null)
            .city(company.getAddress() != null ? company.getAddress().city() : null)
            .state(company.getAddress() != null ? company.getAddress().state() : null)
            .country(company.getAddress() != null ? company.getAddress().country() : null)
            .postalCode(company.getAddress() != null ? company.getAddress().zipCode() : null)
            .industry(company.getActivitySector())
            .employeeCount(1) // Default value
            .timezone("America/Sao_Paulo") // Default value
            .active(company.getStatus().name().equals("ACTIVE"))
            .logoUrl(company.getLogoUrl())
            .settings(Map.of("plan", company.getActivePlan().name()))
            .createdAt(company.getCreatedAt())
            .updatedAt(company.getUpdatedAt())
            .build();
    }
}

