"""
Link Building Strategy Module

This module provides tools for identifying link opportunities, creating link-worthy content,
and managing outreach campaigns for SEO link building.

Requirements: 5.2, 5.3, 5.4, 6.1
"""

import json
from typing import List, Dict, Optional, Tuple
from dataclasses import dataclass, asdict
from enum import Enum
from datetime import datetime


class LinkSourceType(Enum):
    """Types of link sources for categorization."""
    INDUSTRY_PUBLICATION = "industry_publication"
    LOCAL_DIRECTORY = "local_directory"
    BUSINESS_DIRECTORY = "business_directory"
    RESOURCE_PAGE = "resource_page"
    COMPETITOR_BACKLINK = "competitor_backlink"
    GUEST_POST_OPPORTUNITY = "guest_post_opportunity"
    BROKEN_LINK = "broken_link"
    LOCAL_BUSINESS_ASSOCIATION = "local_business_association"


class LinkOpportunityStatus(Enum):
    """Status of link opportunities."""
    IDENTIFIED = "identified"
    CONTACTED = "contacted"
    IN_PROGRESS = "in_progress"
    ACQUIRED = "acquired"
    REJECTED = "rejected"
    PENDING = "pending"


@dataclass
class LinkOpportunity:
    """Represents a link building opportunity."""
    
    id: str
    domain: str
    domain_authority: int
    source_type: LinkSourceType
    url: str
    contact_email: Optional[str] = None
    contact_name: Optional[str] = None
    description: str = ""
    status: LinkOpportunityStatus = LinkOpportunityStatus.IDENTIFIED
    notes: str = ""
    created_at: str = ""
    last_contacted: Optional[str] = None
    
    def __post_init__(self):
        if not self.created_at:
            self.created_at = datetime.now().isoformat()
    
    def to_dict(self) -> Dict:
        """Convert to dictionary for JSON serialization."""
        data = asdict(self)
        data['source_type'] = self.source_type.value
        data['status'] = self.status.value
        return data


class LinkOpportunityIdentifier:
    """Identifies link building opportunities."""
    
    # High-DA industry publications in facilities management
    INDUSTRY_PUBLICATIONS = [
        {
            "domain": "fmworld.co.uk",
            "domain_authority": 58,
            "name": "FM World",
            "description": "Leading UK facilities management publication",
            "contact_email": "editorial@fmworld.co.uk",
            "url": "https://www.fmworld.co.uk"
        },
        {
            "domain": "facilitiesmanagement.co.uk",
            "domain_authority": 52,
            "name": "Facilities Management Association",
            "description": "UK facilities management industry association",
            "contact_email": "info@fmassociation.org.uk",
            "url": "https://www.facilitiesmanagement.co.uk"
        },
        {
            "domain": "ifma.org",
            "domain_authority": 65,
            "name": "IFMA - International Facility Management Association",
            "description": "Global facilities management professional association",
            "contact_email": "info@ifma.org",
            "url": "https://www.ifma.org"
        },
        {
            "domain": "facilitiesnet.com",
            "domain_authority": 61,
            "name": "Facilities.net",
            "description": "Comprehensive facilities management resource",
            "contact_email": "editorial@facilitiesnet.com",
            "url": "https://www.facilitiesnet.com"
        },
        {
            "domain": "facilitiesmanagementjournal.com",
            "domain_authority": 48,
            "name": "Facilities Management Journal",
            "description": "Industry journal for facilities professionals",
            "contact_email": "submissions@fmjournal.com",
            "url": "https://www.facilitiesmanagementjournal.com"
        },
        {
            "domain": "bsria.co.uk",
            "domain_authority": 56,
            "name": "BSRIA",
            "description": "Building Services Research and Information Association",
            "contact_email": "info@bsria.co.uk",
            "url": "https://www.bsria.co.uk"
        },
        {
            "domain": "cibse.org",
            "domain_authority": 62,
            "name": "CIBSE",
            "description": "Chartered Institution of Building Services Engineers",
            "contact_email": "info@cibse.org",
            "url": "https://www.cibse.org"
        },
        {
            "domain": "boma.org",
            "domain_authority": 64,
            "name": "BOMA International",
            "description": "Building Owners and Managers Association",
            "contact_email": "info@boma.org",
            "url": "https://www.boma.org"
        }
    ]
    
    # High-quality business directories
    BUSINESS_DIRECTORIES = [
        {
            "domain": "trustpilot.com",
            "domain_authority": 85,
            "name": "Trustpilot",
            "description": "Customer review platform",
            "url": "https://www.trustpilot.com",
            "category": "reviews"
        },
        {
            "domain": "google.com/business",
            "domain_authority": 100,
            "name": "Google Business Profile",
            "description": "Google's business listing service",
            "url": "https://business.google.com",
            "category": "local"
        },
        {
            "domain": "bing.com/places",
            "domain_authority": 95,
            "name": "Bing Places",
            "description": "Bing's business listing service",
            "url": "https://www.bingplaces.com",
            "category": "local"
        },
        {
            "domain": "yelp.com",
            "domain_authority": 88,
            "name": "Yelp",
            "description": "Business review and directory platform",
            "url": "https://www.yelp.com",
            "category": "reviews"
        },
        {
            "domain": "britishchambers.org.uk",
            "domain_authority": 62,
            "name": "British Chambers of Commerce",
            "description": "UK chamber of commerce network",
            "url": "https://www.britishchambers.org.uk",
            "category": "chamber"
        },
        {
            "domain": "canadianchamber.ca",
            "domain_authority": 58,
            "name": "Canadian Chamber of Commerce",
            "description": "Canadian chamber of commerce network",
            "url": "https://www.canadianchamber.ca",
            "category": "chamber"
        },
        {
            "domain": "dubaichamber.ae",
            "domain_authority": 55,
            "name": "Dubai Chamber of Commerce",
            "description": "UAE chamber of commerce",
            "url": "https://www.dubaichamber.ae",
            "category": "chamber"
        }
    ]
    
    # Local business directories by region
    LOCAL_DIRECTORIES = {
        "uk": [
            {
                "domain": "yell.com",
                "domain_authority": 72,
                "name": "Yell",
                "description": "UK business directory",
                "url": "https://www.yell.com",
                "region": "UK"
            },
            {
                "domain": "threebestrated.co.uk",
                "domain_authority": 58,
                "name": "Three Best Rated",
                "description": "UK business ratings and reviews",
                "url": "https://www.threebestrated.co.uk",
                "region": "UK"
            },
            {
                "domain": "localbusinessguide.co.uk",
                "domain_authority": 45,
                "name": "Local Business Guide",
                "description": "UK local business directory",
                "url": "https://www.localbusinessguide.co.uk",
                "region": "UK"
            }
        ],
        "canada": [
            {
                "domain": "canadianbusiness.com",
                "domain_authority": 62,
                "name": "Canadian Business Directory",
                "description": "Canada business directory",
                "url": "https://www.canadianbusiness.com",
                "region": "Canada"
            },
            {
                "domain": "torontobusiness.com",
                "domain_authority": 48,
                "name": "Toronto Business Directory",
                "description": "Toronto area business directory",
                "url": "https://www.torontobusiness.com",
                "region": "Canada"
            }
        ],
        "uae": [
            {
                "domain": "dubaicompanies.ae",
                "domain_authority": 52,
                "name": "Dubai Companies Directory",
                "description": "UAE business directory",
                "url": "https://www.dubaicompanies.ae",
                "region": "UAE"
            },
            {
                "domain": "uaebusinessdirectory.com",
                "domain_authority": 48,
                "name": "UAE Business Directory",
                "description": "Comprehensive UAE business directory",
                "url": "https://www.uaebusinessdirectory.com",
                "region": "UAE"
            }
        ]
    }
    
    def __init__(self):
        """Initialize the link opportunity identifier."""
        self.opportunities: List[LinkOpportunity] = []
        self._opportunity_counter = 0
    
    def identify_industry_publications(self) -> List[LinkOpportunity]:
        """
        Identify high-DA industry publications in facilities management.
        
        Returns:
            List of LinkOpportunity objects for industry publications
        """
        opportunities = []
        
        for pub in self.INDUSTRY_PUBLICATIONS:
            opportunity = LinkOpportunity(
                id=f"pub_{self._opportunity_counter}",
                domain=pub["domain"],
                domain_authority=pub["domain_authority"],
                source_type=LinkSourceType.INDUSTRY_PUBLICATION,
                url=pub["url"],
                contact_email=pub.get("contact_email"),
                description=pub["description"]
            )
            opportunities.append(opportunity)
            self._opportunity_counter += 1
        
        self.opportunities.extend(opportunities)
        return opportunities
    
    def identify_business_directories(self) -> List[LinkOpportunity]:
        """
        Identify high-quality business directories.
        
        Returns:
            List of LinkOpportunity objects for business directories
        """
        opportunities = []
        
        for directory in self.BUSINESS_DIRECTORIES:
            opportunity = LinkOpportunity(
                id=f"dir_{self._opportunity_counter}",
                domain=directory["domain"],
                domain_authority=directory["domain_authority"],
                source_type=LinkSourceType.BUSINESS_DIRECTORY,
                url=directory["url"],
                description=directory["description"]
            )
            opportunities.append(opportunity)
            self._opportunity_counter += 1
        
        self.opportunities.extend(opportunities)
        return opportunities
    
    def identify_local_directories(self, region: Optional[str] = None) -> List[LinkOpportunity]:
        """
        Identify local business directories by region.
        
        Args:
            region: Region code ('uk', 'canada', 'uae') or None for all regions
        
        Returns:
            List of LinkOpportunity objects for local directories
        """
        opportunities = []
        regions_to_search = [region] if region else self.LOCAL_DIRECTORIES.keys()
        
        for reg in regions_to_search:
            if reg not in self.LOCAL_DIRECTORIES:
                continue
            
            for directory in self.LOCAL_DIRECTORIES[reg]:
                opportunity = LinkOpportunity(
                    id=f"local_{self._opportunity_counter}",
                    domain=directory["domain"],
                    domain_authority=directory["domain_authority"],
                    source_type=LinkSourceType.LOCAL_DIRECTORY,
                    url=directory["url"],
                    description=directory["description"]
                )
                opportunities.append(opportunity)
                self._opportunity_counter += 1
        
        self.opportunities.extend(opportunities)
        return opportunities
    
    def identify_all_opportunities(self) -> List[LinkOpportunity]:
        """
        Identify all link building opportunities.
        
        Returns:
            List of all identified LinkOpportunity objects
        """
        self.opportunities = []
        self._opportunity_counter = 0
        
        self.identify_industry_publications()
        self.identify_business_directories()
        self.identify_local_directories()
        
        return self.opportunities
    
    def filter_by_domain_authority(self, min_da: int) -> List[LinkOpportunity]:
        """
        Filter opportunities by minimum domain authority.
        
        Args:
            min_da: Minimum domain authority threshold
        
        Returns:
            Filtered list of opportunities
        """
        return [opp for opp in self.opportunities if opp.domain_authority >= min_da]
    
    def filter_by_source_type(self, source_type: LinkSourceType) -> List[LinkOpportunity]:
        """
        Filter opportunities by source type.
        
        Args:
            source_type: Type of link source to filter by
        
        Returns:
            Filtered list of opportunities
        """
        return [opp for opp in self.opportunities if opp.source_type == source_type]
    
    def get_top_opportunities(self, limit: int = 20) -> List[LinkOpportunity]:
        """
        Get top link opportunities sorted by domain authority.
        
        Args:
            limit: Maximum number of opportunities to return
        
        Returns:
            Top opportunities sorted by domain authority (descending)
        """
        sorted_opps = sorted(
            self.opportunities,
            key=lambda x: x.domain_authority,
            reverse=True
        )
        return sorted_opps[:limit]
    
    def export_opportunities(self, filepath: str) -> None:
        """
        Export identified opportunities to JSON file.
        
        Args:
            filepath: Path to export JSON file
        """
        data = [opp.to_dict() for opp in self.opportunities]
        with open(filepath, 'w') as f:
            json.dump(data, f, indent=2)


class LinkWorthyContentCreator:
    """Creates link-worthy content for link building campaigns."""
    
    @dataclass
    class ContentPiece:
        """Represents a link-worthy content piece."""
        title: str
        description: str
        content_type: str
        estimated_links: int
        target_keywords: List[str]
        resources_needed: List[str]
        timeline_weeks: int
    
    # Link-worthy content ideas
    CONTENT_IDEAS = [
        {
            "title": "State of Facilities Management 2024: Industry Report",
            "description": "Comprehensive industry report with original research on facilities management trends, challenges, and opportunities",
            "content_type": "research_report",
            "estimated_links": 25,
            "target_keywords": ["facilities management trends", "industry report", "facilities management statistics"],
            "resources_needed": ["survey tool", "data analyst", "designer", "writer"],
            "timeline_weeks": 8
        },
        {
            "title": "Facilities Management Cost Reduction Calculator",
            "description": "Interactive tool that helps facilities managers calculate potential cost savings",
            "content_type": "tool",
            "estimated_links": 15,
            "target_keywords": ["cost reduction", "facilities management calculator", "ROI calculator"],
            "resources_needed": ["developer", "designer", "facilities expert"],
            "timeline_weeks": 4
        },
        {
            "title": "Complete Guide to Facilities Management: 5000+ Word Resource",
            "description": "Comprehensive guide covering all aspects of facilities management",
            "content_type": "guide",
            "estimated_links": 20,
            "target_keywords": ["facilities management guide", "complete guide", "how to"],
            "resources_needed": ["writer", "designer", "editor"],
            "timeline_weeks": 6
        },
        {
            "title": "Facilities Management Benchmarking Study",
            "description": "Original research comparing facilities management practices across industries",
            "content_type": "research_study",
            "estimated_links": 30,
            "target_keywords": ["benchmarking", "best practices", "industry comparison"],
            "resources_needed": ["researcher", "data analyst", "writer"],
            "timeline_weeks": 10
        },
        {
            "title": "Facilities Management ROI Calculator",
            "description": "Tool to calculate return on investment for facilities management initiatives",
            "content_type": "tool",
            "estimated_links": 12,
            "target_keywords": ["ROI", "return on investment", "facilities management"],
            "resources_needed": ["developer", "designer"],
            "timeline_weeks": 3
        },
        {
            "title": "Facilities Management Checklist: 100-Point Audit",
            "description": "Downloadable checklist for facilities management audits",
            "content_type": "checklist",
            "estimated_links": 18,
            "target_keywords": ["checklist", "audit", "facilities management"],
            "resources_needed": ["writer", "designer"],
            "timeline_weeks": 2
        },
        {
            "title": "Facilities Management Salary Survey 2024",
            "description": "Original survey of facilities management salaries and compensation",
            "content_type": "survey",
            "estimated_links": 22,
            "target_keywords": ["salary survey", "compensation", "careers"],
            "resources_needed": ["researcher", "data analyst", "writer"],
            "timeline_weeks": 6
        },
        {
            "title": "Facilities Management Technology Comparison Guide",
            "description": "Comprehensive comparison of facilities management software and tools",
            "content_type": "comparison_guide",
            "estimated_links": 16,
            "target_keywords": ["software comparison", "technology", "tools"],
            "resources_needed": ["writer", "designer", "tech expert"],
            "timeline_weeks": 5
        }
    ]
    
    def __init__(self):
        """Initialize the link-worthy content creator."""
        self.content_pieces: List[self.ContentPiece] = []
    
    def create_content_plan(self) -> List[ContentPiece]:
        """
        Create a plan for link-worthy content.
        
        Returns:
            List of ContentPiece objects representing planned content
        """
        self.content_pieces = []
        
        for idea in self.CONTENT_IDEAS:
            piece = self.ContentPiece(
                title=idea["title"],
                description=idea["description"],
                content_type=idea["content_type"],
                estimated_links=idea["estimated_links"],
                target_keywords=idea["target_keywords"],
                resources_needed=idea["resources_needed"],
                timeline_weeks=idea["timeline_weeks"]
            )
            self.content_pieces.append(piece)
        
        return self.content_pieces
    
    def get_high_impact_content(self, min_estimated_links: int = 15) -> List[ContentPiece]:
        """
        Get high-impact content pieces.
        
        Args:
            min_estimated_links: Minimum estimated links for content
        
        Returns:
            List of high-impact content pieces
        """
        return [
            piece for piece in self.content_pieces
            if piece.estimated_links >= min_estimated_links
        ]
    
    def get_quick_wins(self, max_timeline_weeks: int = 3) -> List[ContentPiece]:
        """
        Get quick-win content pieces that can be created quickly.
        
        Args:
            max_timeline_weeks: Maximum timeline in weeks
        
        Returns:
            List of quick-win content pieces
        """
        return [
            piece for piece in self.content_pieces
            if piece.timeline_weeks <= max_timeline_weeks
        ]
    
    def export_content_plan(self, filepath: str) -> None:
        """
        Export content plan to JSON file.
        
        Args:
            filepath: Path to export JSON file
        """
        data = []
        for piece in self.content_pieces:
            data.append({
                "title": piece.title,
                "description": piece.description,
                "content_type": piece.content_type,
                "estimated_links": piece.estimated_links,
                "target_keywords": piece.target_keywords,
                "resources_needed": piece.resources_needed,
                "timeline_weeks": piece.timeline_weeks
            })
        
        with open(filepath, 'w') as f:
            json.dump(data, f, indent=2)


class OutreachStrategy:
    """Manages link building outreach strategy."""
    
    @dataclass
    class OutreachTemplate:
        """Represents an outreach email template."""
        name: str
        subject: str
        body: str
        use_case: str
    
    # Outreach email templates
    OUTREACH_TEMPLATES = [
        {
            "name": "guest_post_pitch",
            "subject": "Guest Post Opportunity: [TOPIC] for [PUBLICATION]",
            "body": """Hi [CONTACT_NAME],

I've been following [PUBLICATION] for a while and really appreciate your content on [TOPIC].

I'd like to contribute a guest post on [SPECIFIC_TOPIC] that I think would resonate with your audience. The article would cover [KEY_POINTS] and provide actionable insights for facilities managers.

Here are a few article ideas:
- [IDEA_1]
- [IDEA_2]
- [IDEA_3]

I'm happy to discuss any of these topics or suggest alternatives based on your editorial calendar.

Best regards,
[YOUR_NAME]
[YOUR_TITLE]
[COMPANY_NAME]
[CONTACT_INFO]""",
            "use_case": "guest_posting"
        },
        {
            "name": "resource_page_link",
            "subject": "Resource for Your [TOPIC] Page",
            "body": """Hi [CONTACT_NAME],

I came across your excellent resource page on [TOPIC] at [URL].

I recently created a comprehensive guide on [RELATED_TOPIC] that I think would be a great addition to your resources. It covers [KEY_POINTS] and has been well-received by facilities management professionals.

You can check it out here: [RESOURCE_URL]

I'd love to see it included in your resource list if you think it would be valuable for your audience.

Best regards,
[YOUR_NAME]
[YOUR_TITLE]
[COMPANY_NAME]
[CONTACT_INFO]""",
            "use_case": "resource_page"
        },
        {
            "name": "broken_link_replacement",
            "subject": "Replacement for Broken Link on [PUBLICATION]",
            "body": """Hi [CONTACT_NAME],

I noticed that your article on [TOPIC] has a broken link to [BROKEN_LINK].

I have a comprehensive resource on [RELATED_TOPIC] that would be a perfect replacement. It covers similar content and is regularly updated.

You can find it here: [REPLACEMENT_URL]

Let me know if you'd like to update the link!

Best regards,
[YOUR_NAME]
[YOUR_TITLE]
[COMPANY_NAME]
[CONTACT_INFO]""",
            "use_case": "broken_link_building"
        },
        {
            "name": "collaboration_opportunity",
            "subject": "Collaboration Opportunity: [PROJECT_NAME]",
            "body": """Hi [CONTACT_NAME],

I've been impressed with your work on [TOPIC] and think we could create something great together.

We're launching [PROJECT_NAME] and would love to collaborate with [PUBLICATION] on [SPECIFIC_COLLABORATION].

This would involve:
- [COLLABORATION_POINT_1]
- [COLLABORATION_POINT_2]
- [COLLABORATION_POINT_3]

I think this would be valuable for both our audiences. Would you be interested in discussing this further?

Best regards,
[YOUR_NAME]
[YOUR_TITLE]
[COMPANY_NAME]
[CONTACT_INFO]""",
            "use_case": "collaboration"
        }
    ]
    
    def __init__(self):
        """Initialize the outreach strategy."""
        self.templates: List[self.OutreachTemplate] = []
        self.contacts: List[Dict] = []
    
    def load_templates(self) -> List[OutreachTemplate]:
        """
        Load outreach email templates.
        
        Returns:
            List of OutreachTemplate objects
        """
        self.templates = []
        
        for template_data in self.OUTREACH_TEMPLATES:
            template = self.OutreachTemplate(
                name=template_data["name"],
                subject=template_data["subject"],
                body=template_data["body"],
                use_case=template_data["use_case"]
            )
            self.templates.append(template)
        
        return self.templates
    
    def get_template(self, use_case: str) -> Optional[OutreachTemplate]:
        """
        Get template by use case.
        
        Args:
            use_case: Use case identifier
        
        Returns:
            OutreachTemplate or None if not found
        """
        for template in self.templates:
            if template.use_case == use_case:
                return template
        return None
    
    def personalize_template(
        self,
        template: OutreachTemplate,
        replacements: Dict[str, str]
    ) -> str:
        """
        Personalize a template with specific values.
        
        Args:
            template: OutreachTemplate to personalize
            replacements: Dictionary of placeholder replacements
        
        Returns:
            Personalized email body
        """
        body = template.body
        
        for placeholder, value in replacements.items():
            body = body.replace(f"[{placeholder}]", value)
        
        return body
    
    def add_contact(
        self,
        name: str,
        email: str,
        publication: str,
        domain_authority: int,
        contact_type: str
    ) -> Dict:
        """
        Add a contact for outreach.
        
        Args:
            name: Contact name
            email: Contact email
            publication: Publication/organization name
            domain_authority: Domain authority of publication
            contact_type: Type of contact (editor, publisher, etc.)
        
        Returns:
            Contact dictionary
        """
        contact = {
            "id": len(self.contacts),
            "name": name,
            "email": email,
            "publication": publication,
            "domain_authority": domain_authority,
            "contact_type": contact_type,
            "added_at": datetime.now().isoformat()
        }
        self.contacts.append(contact)
        return contact
    
    def export_contacts(self, filepath: str) -> None:
        """
        Export contacts to JSON file.
        
        Args:
            filepath: Path to export JSON file
        """
        with open(filepath, 'w') as f:
            json.dump(self.contacts, f, indent=2)
    
    def export_templates(self, filepath: str) -> None:
        """
        Export templates to JSON file.
        
        Args:
            filepath: Path to export JSON file
        """
        data = [
            {
                "name": t.name,
                "subject": t.subject,
                "body": t.body,
                "use_case": t.use_case
            }
            for t in self.templates
        ]
        with open(filepath, 'w') as f:
            json.dump(data, f, indent=2)
