# Business Logic Service for Lead Management
from typing import List, Dict, Any, Optional
from uuid import UUID
from datetime import datetime
from .repositories import LeadRepository

class LeadService:
    def __init__(self, repository: LeadRepository):
        self.repo = repository
    
    # Institution Services
    def list_institutions(self) -> List[Dict[str, Any]]:
        """Get all institutions with contact counts"""
        return self.repo.get_institutions_with_counts()
    
    def create_institution(self, name: str, user: str) -> Dict[str, Any]:
        """Create a new institution"""
        # Validation
        if not name or len(name.strip()) == 0:
            raise ValueError("Institution name cannot be empty")
        
        # Create institution
        institution = self.repo.create_institution(name.strip(), user)
        
        # Note: Audit logging removed as it requires different implementation
        # Can be added later with proper audit system integration
        
        return institution
    
    def update_institution(self, institution_id: UUID, name: str, user: str) -> Dict[str, Any]:
        """Update institution name"""
        # Validation
        if not name or len(name.strip()) == 0:
            raise ValueError("Institution name cannot be empty")
        
        # Get current institution
        current = self.repo.get_institution_by_id(institution_id)
        if not current:
            raise ValueError("Institution not found")
        
        # Update
        institution = self.repo.update_institution(institution_id, name.strip())
        
        return institution
    
    # Contact Services
    def list_contacts_by_institution(self, institution_id: UUID) -> List[Dict[str, Any]]:
        """Get all contacts for an institution"""
        return self.repo.get_contacts_by_institution(institution_id)
    
    def create_contact(self, data: Dict[str, Any], user: str) -> Dict[str, Any]:
        """Create a new contact"""
        # Validation
        if not data.get('first_name') or not data.get('last_name'):
            raise ValueError("First and last name are required")
        
        if not data.get('institution_id'):
            raise ValueError("Institution ID is required")
        
        # Create contact
        contact = self.repo.create_contact(data)
        
        return contact
    
    def get_contact_details(self, contact_id: UUID) -> Dict[str, Any]:
        """Get full contact information including details and notes"""
        contact = self.repo.get_contact_with_details(contact_id)
        if not contact:
            raise ValueError("Contact not found")
        
        # Group details by type
        contact['phones'] = [d for d in contact.get('details', []) if d['detail_type'] == 'phone']
        contact['emails'] = [d for d in contact.get('details', []) if d['detail_type'] == 'email']
        
        return contact
    
    def update_contact(self, contact_id: UUID, data: Dict[str, Any], user: str) -> Dict[str, Any]:
        """Update contact information"""
        # Validation
        if not data.get('first_name') or not data.get('last_name'):
            raise ValueError("First and last name are required")
        
        # Update contact
        contact = self.repo.update_contact(contact_id, data)
        
        return contact
    
    # Contact Details Services
    def add_phone(self, contact_id: UUID, phone_number: str, 
                  phone_type: str = None, user: str = None) -> Dict[str, Any]:
        """Add phone number to contact"""
        if not phone_number:
            raise ValueError("Phone number is required")
        
        detail = self.repo.add_contact_detail(
            contact_id, 'phone', phone_number, phone_type
        )
        
        return detail
    
    def add_email(self, contact_id: UUID, email: str, 
                  email_type: str = None, user: str = None) -> Dict[str, Any]:
        """Add email to contact"""
        if not email:
            raise ValueError("Email is required")
        
        # Basic email validation
        if '@' not in email:
            raise ValueError("Invalid email format")
        
        detail = self.repo.add_contact_detail(
            contact_id, 'email', email, email_type
        )
        
        return detail
    
    def update_contact_detail(self, detail_id: UUID, detail_value: str, 
                            detail_label: str = None, user: str = None) -> Dict[str, Any]:
        """Update a contact detail (phone/email)"""
        if not detail_value or len(detail_value.strip()) == 0:
            raise ValueError("Detail value cannot be empty")
        
        # Get current detail to check type
        current_detail = self.repo.get_contact_detail_by_id(detail_id)
        if not current_detail:
            raise ValueError("Contact detail not found")
        
        # Validation based on type
        if current_detail['detail_type'] == 'email' and '@' not in detail_value:
            raise ValueError("Invalid email format")
        
        detail = self.repo.update_contact_detail(
            detail_id, detail_value.strip(), detail_label
        )
        
        return detail
    
    def delete_contact_detail(self, detail_id: UUID, user: str) -> bool:
        """Delete a contact detail (phone/email)"""
        success = self.repo.delete_contact_detail(detail_id)
        
        return success
    
    # Note Services
    def add_note(self, contact_id: UUID, note_text: str, user: str) -> Dict[str, Any]:
        """Add a note to contact"""
        if not note_text or len(note_text.strip()) == 0:
            raise ValueError("Note text cannot be empty")
        
        note = self.repo.create_note(contact_id, note_text.strip(), user)
        
        return note
    
    def update_note(self, note_id: UUID, note_text: str, user: str) -> Dict[str, Any]:
        """Update a note (creates new version)"""
        if not note_text or len(note_text.strip()) == 0:
            raise ValueError("Note text cannot be empty")
        
        note = self.repo.update_note(note_id, note_text.strip(), user)
        
        return note
    
    def delete_note(self, note_id: UUID, user: str) -> bool:
        """Delete a note (soft delete)"""
        success = self.repo.delete_note(note_id)
        
        return success
    
    def list_all_contacts(self) -> List[Dict[str, Any]]:
        """Get all contacts across all institutions with summary info"""
        return self.repo.get_all_contacts_with_institutions()