package com.social.media.application.usecases.company;

import com.social.media.application.ports.out.CompanyRepositoryPort;
import com.social.media.domain.company.entities.Company;
import com.social.media.domain.company.valueobjects.CompanyPlan;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * Use case for creating a new company.
 * 
 * Handles the business logic for company registration including
 * validation and initial setup.
 * 
 * @author Social Media Manager Team
 * @since 2.0.0
 */
@Service
@RequiredArgsConstructor
@Transactional
public class CreateCompanyUseCase {
    
    private final CompanyRepositoryPort companyRepository;
    
    public record CreateCompanyCommand(
        String name,
        String description,
        String contactEmail,
        CompanyPlan.PlanType planType,
        String timezone,
        String language,
        String websiteUrl
    ) {}
    
    public record CreateCompanyResult(
        String companyUuid,
        String name,
        String contactEmail,
        CompanyPlan.PlanType planType,
        boolean isInTrial
    ) {}
    
    /**
     * Execute the create company use case
     */
    public CreateCompanyResult execute(CreateCompanyCommand command) {
        // Validate business rules
        validateCreateCompanyCommand(command);
        
        // Check if company with email already exists
        if (companyRepository.existsByContactEmail(command.contactEmail())) {
            throw new IllegalArgumentException("Company with this email already exists");
        }
        
        // Create new company
        Company company = Company.create(
            command.name(),
            command.description(),
            command.contactEmail(),
            command.planType(),
            command.timezone(),
            command.language()
        );
        
        // Set optional website URL
        if (command.websiteUrl() != null && !command.websiteUrl().trim().isEmpty()) {
            company.setWebsiteUrl(command.websiteUrl().trim());
        }
        
        // Save company
        Company savedCompany = companyRepository.save(company);
        
        // Return result
        return new CreateCompanyResult(
            savedCompany.getCompanyUuid(),
            savedCompany.getName(),
            savedCompany.getContactEmail(),
            savedCompany.getPlan().getPlanType(),
            savedCompany.isInTrial()
        );
    }
    
    /**
     * Validate the create company command
     */
    private void validateCreateCompanyCommand(CreateCompanyCommand command) {
        if (command.name() == null || command.name().trim().isEmpty()) {
            throw new IllegalArgumentException("Company name is required");
        }
        
        if (command.contactEmail() == null || command.contactEmail().trim().isEmpty()) {
            throw new IllegalArgumentException("Contact email is required");
        }
        
        if (command.planType() == null) {
            throw new IllegalArgumentException("Plan type is required");
        }
        
        if (command.timezone() == null || command.timezone().trim().isEmpty()) {
            throw new IllegalArgumentException("Timezone is required");
        }
        
        if (command.language() == null || command.language().trim().isEmpty()) {
            throw new IllegalArgumentException("Language is required");
        }
        
        // Validate timezone format (basic validation)
        if (!isValidTimezone(command.timezone())) {
            throw new IllegalArgumentException("Invalid timezone format");
        }
        
        // Validate language format (basic validation)
        if (!isValidLanguage(command.language())) {
            throw new IllegalArgumentException("Invalid language format");
        }
    }
    
    /**
     * Basic timezone validation
     */
    private boolean isValidTimezone(String timezone) {
        try {
            java.time.ZoneId.of(timezone);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * Basic language validation (ISO 639-1 codes)
     */
    private boolean isValidLanguage(String language) {
        return language.matches("^[a-z]{2}$");
    }
}
