package com.social.media.application.company.handler;

import com.social.media.application.company.command.CreateCompanyCommand;
import com.social.media.application.ports.CompanyRepository;
import com.social.media.domain.company.Company;
import com.social.media.domain.company.Cnpj;
import com.social.media.domain.company.Email;
import com.social.media.domain.company.Address;
import com.social.media.domain.shared.enums.CompanyPlan;
import com.social.media.domain.shared.enums.CompanyStatus;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

/**
 * Handler for creating new companies.
 * Implements the complete business logic for company registration.
 */
@Component
public class CreateCompanyHandler {
    
    private final CompanyRepository companyRepository;
    
    public CreateCompanyHandler(CompanyRepository companyRepository) {
        this.companyRepository = companyRepository;
    }
    
    @Transactional
    public UUID handle(CreateCompanyCommand command) {
        // Validate business rules
        validateBusinessRules(command);
        
        // Create value objects
        Cnpj cnpj = new Cnpj(command.cnpj());
        Email email = new Email(command.email());
        Address address = createAddress(command);
        CompanyPlan plan = CompanyPlan.valueOf(command.plan().toUpperCase());
        
        // Create company entity
        Company company = new Company(
            UUID.randomUUID(),
            command.companyName(),
            command.cnpj(),
            command.email(),
            plan,
            address
        );
        
        // Set optional fields using updateBasicInfo method
        company.updateBasicInfo(
            command.companyName(), 
            command.phoneNumber(), 
            command.website(), 
            command.activitySector()
        );
        
        // Save company
        Company savedCompany = companyRepository.save(company);
        
        // TODO: Publish domain event for company creation
        // publishCompanyCreatedEvent(savedCompany, command.createdByUserId());
        
        return savedCompany.getId();
    }
    
    private void validateBusinessRules(CreateCompanyCommand command) {
        // Check if CNPJ already exists
        if (companyRepository.existsByCnpj(command.cnpj())) {
            throw new IllegalArgumentException("A company with this CNPJ already exists");
        }
        
        // Check if email already exists
        if (companyRepository.existsByEmail(command.email())) {
            throw new IllegalArgumentException("A company with this email already exists");
        }
        
        // Validate plan
        try {
            CompanyPlan.valueOf(command.plan().toUpperCase());
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("Invalid company plan: " + command.plan());
        }
    }
    
    private Address createAddress(CreateCompanyCommand command) {
        return new Address(
            command.street(),
            command.number(),
            command.complement(),
            command.neighborhood(),
            command.city(),
            command.state(),
            command.postalCode(),
            command.country() != null ? command.country() : "Brazil"
        );
    }
    
    // TODO: Implement event publishing
    // private void publishCompanyCreatedEvent(Company company, UUID createdByUserId) {
    //     CompanyCreatedEvent event = new CompanyCreatedEvent(
    //         company.getId(),
    //         company.getCompanyName(),
    //         company.getCnpj().getValue(),
    //         company.getEmail().getValue(),
    //         createdByUserId,
    //         LocalDateTime.now()
    //     );
    //     eventPublisher.publish(event);
    // }
}
