import pandas as pd
import numpy as np
from pathlib import Path
import json
from collections import Counter, defaultdict
import re


def analyze_apollo_contacts(file_path):
    """Comprehensive analysis of Apollo contacts export"""

    print(f"Loading file: {file_path}")
    df = pd.read_csv(file_path, low_memory=False)

    print(f"\n{'='*60}")
    print(f"BASIC STATISTICS")
    print(f"{'='*60}")
    print(f"Total contacts: {len(df):,}")
    print(f"Total columns: {len(df.columns)}")
    print(f"File size: {Path(file_path).stat().st_size / 1024 / 1024:.2f} MB")

    # Column analysis
    print(f"\n{'='*60}")
    print(f"COLUMNS AVAILABLE")
    print(f"{'='*60}")
    for i, col in enumerate(df.columns, 1):
        non_null = df[col].notna().sum()
        fill_rate = (non_null / len(df)) * 100
        print(f"{i:2d}. {col:<40} ({fill_rate:5.1f}% filled)")

    # Key fields analysis
    print(f"\n{'='*60}")
    print(f"KEY FIELD ANALYSIS")
    print(f"{'='*60}")

    # Email patterns
    if "Email" in df.columns:
        email_domains = df["Email"].dropna().str.split("@").str[1].value_counts()
        print(f"\nEmail Analysis:")
        print(f"  - Unique emails: {df['Email'].nunique():,}")
        print(f"  - Fill rate: {(df['Email'].notna().sum() / len(df)) * 100:.1f}%")
        print(f"  - Unique domains: {len(email_domains):,}")
        print(f"  - Top 5 domains:")
        for domain, count in email_domains.head().items():
            print(f"    - {domain}: {count:,} ({count/len(df)*100:.1f}%)")

        # Email format patterns
        email_patterns = analyze_email_patterns(df["Email"].dropna())
        print(f"\n  Email format patterns:")
        for pattern, pct in email_patterns.items():
            print(f"    - {pattern}: {pct:.1f}%")

    # Title analysis
    if "Title" in df.columns:
        print(f"\nTitle Analysis:")
        titles = df["Title"].dropna()
        print(f"  - Unique titles: {titles.nunique():,}")
        print(f"  - Fill rate: {(titles.notna().sum() / len(df)) * 100:.1f}%")
        print(f"  - Top 10 titles:")
        for title, count in titles.value_counts().head(10).items():
            print(f"    - {title}: {count:,}")

        # Title patterns
        title_patterns = analyze_title_patterns(titles)
        print(f"\n  Common title components:")
        for component, count in title_patterns.most_common(10):
            print(f"    - {component}: {count:,}")

    # Company analysis
    company_col = None
    for col in ["Company", "Account Name", "Organization Name"]:
        if col in df.columns:
            company_col = col
            break

    if company_col:
        print(f"\nCompany Analysis (using '{company_col}'):")
        companies = df[company_col].dropna()
        print(f"  - Unique companies: {companies.nunique():,}")
        print(f"  - Contacts per company:")
        contacts_per_company = df[company_col].value_counts()
        print(f"    - Average: {contacts_per_company.mean():.1f}")
        print(f"    - Median: {contacts_per_company.median():.0f}")
        print(f"    - Max: {contacts_per_company.max():,}")
        print(f"  - Top 5 companies by contact count:")
        for company, count in contacts_per_company.head().items():
            print(f"    - {company}: {count:,} contacts")

    # Name analysis
    if "First Name" in df.columns and "Last Name" in df.columns:
        print(f"\nName Analysis:")
        first_names = df["First Name"].dropna()
        last_names = df["Last Name"].dropna()
        print(f"  - Unique first names: {first_names.nunique():,}")
        print(f"  - Unique last names: {last_names.nunique():,}")
        print(f"  - Most common first names:")
        for name, count in first_names.value_counts().head(5).items():
            print(f"    - {name}: {count:,}")

    # Phone analysis
    phone_cols = [col for col in df.columns if "Phone" in col or "Mobile" in col]
    if phone_cols:
        print(f"\nPhone Analysis:")
        for col in phone_cols:
            if col in df.columns:
                fill_rate = (df[col].notna().sum() / len(df)) * 100
                print(f"  - {col}: {fill_rate:.1f}% fill rate")

    # Domain/Website analysis
    domain_col = None
    for col in ["Website", "Domain", "Company Domain"]:
        if col in df.columns:
            domain_col = col
            break

    if domain_col:
        print(f"\nDomain Analysis (using '{domain_col}'):")
        domains = df[domain_col].dropna()
        print(f"  - Unique domains: {domains.nunique():,}")
        print(f"  - Fill rate: {(len(domains) / len(df)) * 100:.1f}%")

    # Location analysis
    location_cols = [
        col
        for col in df.columns
        if any(x in col.lower() for x in ["city", "state", "country", "location"])
    ]
    if location_cols:
        print(f"\nLocation Fields Available:")
        for col in location_cols:
            fill_rate = (df[col].notna().sum() / len(df)) * 100
            unique_count = df[col].nunique()
            print(
                f"  - {col}: {unique_count:,} unique values ({fill_rate:.1f}% filled)"
            )

    # Seniority/Department analysis
    for field in ["Seniority", "Department", "Job Function"]:
        if field in df.columns:
            print(f"\n{field} Distribution:")
            for value, count in df[field].value_counts().head(5).items():
                print(f"  - {value}: {count:,} ({count/len(df)*100:.1f}%)")

    return df


def analyze_email_patterns(emails):
    """Analyze email format patterns"""
    patterns = defaultdict(int)

    for email in emails:
        if "@" not in email:
            continue

        local_part = email.split("@")[0].lower()

        # Check common patterns
        if "." in local_part:
            parts = local_part.split(".")
            if len(parts) == 2 and len(parts[0]) > 1 and len(parts[1]) > 1:
                patterns["firstname.lastname"] += 1
            elif len(parts) == 2 and len(parts[0]) == 1:
                patterns["f.lastname"] += 1
        elif "_" in local_part:
            patterns["firstname_lastname"] += 1
        elif local_part.isalpha() and len(local_part) < 10:
            patterns["firstname"] += 1
        elif (
            len(local_part) > 1 and local_part[0].isalpha() and local_part[1:].isalpha()
        ):
            patterns["flastname"] += 1
        else:
            patterns["other"] += 1

    total = sum(patterns.values())
    return {k: (v / total) * 100 for k, v in patterns.items()}


def analyze_title_patterns(titles):
    """Extract common title components"""
    components = Counter()

    # Common title keywords
    keywords = [
        "Vice President",
        "VP",
        "Director",
        "Manager",
        "Head of",
        "Chief",
        "Senior",
        "Sr",
        "Lead",
        "Principal",
        "Executive",
        "Specialist",
        "Analyst",
        "Engineer",
        "Developer",
        "Consultant",
        "Coordinator",
        "Sales",
        "Marketing",
        "Operations",
        "Finance",
        "IT",
        "HR",
        "Product",
        "Business",
        "Development",
        "Customer",
        "Account",
    ]

    for title in titles:
        title_upper = title.upper()
        for keyword in keywords:
            if keyword.upper() in title_upper:
                components[keyword] += 1

    return components


# Run the analysis
if __name__ == "__main__":
    import sys
    import os

    # Look for the file in Downloads
    downloads_dir = Path.home() / "Downloads"

    # Find Apollo contact files
    apollo_files = (
        list(downloads_dir.glob("*apollo*contact*.csv"))
        + list(downloads_dir.glob("*contact*apollo*.csv"))
        + list(downloads_dir.glob("apollo*.csv"))
    )

    if apollo_files:
        print("Found Apollo contact files:")
        for i, file in enumerate(apollo_files):
            print(f"{i+1}. {file.name} ({file.stat().st_size / 1024 / 1024:.2f} MB)")

        if len(apollo_files) == 1:
            file_to_analyze = apollo_files[0]
        else:
            choice = input("\nWhich file to analyze? (enter number): ")
            file_to_analyze = apollo_files[int(choice) - 1]

        df = analyze_apollo_contacts(file_to_analyze)

        # Save analysis results
        output_dir = Path("C:/Users/Mikeh/python/Fuzzy_matcher/test_data/apollo_base")
        output_dir.mkdir(parents=True, exist_ok=True)

        # Save the contacts file
        output_path = output_dir / "apollo_contacts_raw.csv"
        df.to_csv(output_path, index=False)
        print(f"\nSaved contacts to: {output_path}")

        # Save column mapping
        column_map = {
            "columns": list(df.columns),
            "shape": list(df.shape),
            "key_fields": {
                "email": next(
                    (col for col in df.columns if "email" in col.lower()), None
                ),
                "first_name": next(
                    (
                        col
                        for col in df.columns
                        if "first" in col.lower() and "name" in col.lower()
                    ),
                    None,
                ),
                "last_name": next(
                    (
                        col
                        for col in df.columns
                        if "last" in col.lower() and "name" in col.lower()
                    ),
                    None,
                ),
                "company": next(
                    (
                        col
                        for col in df.columns
                        if any(
                            x in col.lower()
                            for x in ["company", "account", "organization"]
                        )
                    ),
                    None,
                ),
                "title": next(
                    (col for col in df.columns if "title" in col.lower()), None
                ),
                "domain": next(
                    (
                        col
                        for col in df.columns
                        if any(x in col.lower() for x in ["domain", "website"])
                    ),
                    None,
                ),
            },
        }

        with open(output_dir / "apollo_contacts_schema.json", "w") as f:
            json.dump(column_map, f, indent=2)

        print(
            f"\nSaved schema mapping to: {output_dir / 'apollo_contacts_schema.json'}"
        )

    else:
        print("No Apollo contact files found in Downloads directory")
        print(f"Looking in: {downloads_dir}")
