#!/usr/bin/env python3
"""
01_fetch_financials.py - M&A Target Financial Screening

Fetches real-time financial data for cybersecurity M&A targets
and applies screening criteria for market cap and revenue growth.

Targets: SentinelOne (S), Zscaler (ZS), CyberArk (CYBR), Tenable (TENB), Rapid7 (RPD)

Screening Criteria:
- Market Cap: $2B - $15B
- Revenue Growth: > 20%
"""

import yfinance as yf
import pandas as pd
import numpy as np
from datetime import datetime
import warnings
warnings.filterwarnings('ignore')

# Configuration
SESSION_DIR = "/app/sandbox/session_20260203_085757_d926b2c7d1fb"
RESULTS_DIR = f"{SESSION_DIR}/results"

# M&A Target Tickers
TARGETS = {
    'S': 'SentinelOne',
    'ZS': 'Zscaler',
    'CYBR': 'CyberArk',
    'TENB': 'Tenable',
    'RPD': 'Rapid7'
}

# Screening Criteria
MARKET_CAP_MIN = 2e9   # $2 Billion
MARKET_CAP_MAX = 15e9  # $15 Billion
REVENUE_GROWTH_MIN = 0.20  # 20%


def format_billions(value):
    """Format value in billions with 2 decimal places."""
    if pd.isna(value) or value is None:
        return "N/A"
    return f"${value/1e9:.2f}B"


def format_percentage(value):
    """Format value as percentage."""
    if pd.isna(value) or value is None:
        return "N/A"
    return f"{value*100:.1f}%"


def fetch_financial_data(ticker_symbol, company_name):
    """
    Fetch comprehensive financial data for a single ticker.

    Parameters
    ----------
    ticker_symbol : str
        Stock ticker symbol
    company_name : str
        Company name for display

    Returns
    -------
    dict
        Dictionary containing all financial metrics
    """
    print(f"  Fetching data for {company_name} ({ticker_symbol})...")

    try:
        ticker = yf.Ticker(ticker_symbol)
        info = ticker.info

        # Extract key metrics
        current_price = info.get('currentPrice') or info.get('regularMarketPrice')
        market_cap = info.get('marketCap')
        enterprise_value = info.get('enterpriseValue')

        # Revenue metrics
        total_revenue = info.get('totalRevenue')
        revenue_growth = info.get('revenueGrowth')  # Quarterly YoY

        # Alternative revenue growth calculation if not directly available
        if revenue_growth is None:
            # Try to get from financials
            try:
                financials = ticker.quarterly_financials
                if financials is not None and not financials.empty:
                    if 'Total Revenue' in financials.index:
                        revenues = financials.loc['Total Revenue'].dropna()
                        if len(revenues) >= 5:  # Need at least 5 quarters for YoY
                            current_q = revenues.iloc[0]
                            year_ago_q = revenues.iloc[4]
                            if year_ago_q > 0:
                                revenue_growth = (current_q - year_ago_q) / year_ago_q
            except Exception as e:
                print(f"    Warning: Could not calculate revenue growth: {e}")

        # Forward estimates for revenue growth
        forward_pe = info.get('forwardPE')
        earnings_growth = info.get('earningsGrowth')

        # Calculate EV/Revenue multiple
        ev_revenue = None
        if enterprise_value and total_revenue and total_revenue > 0:
            ev_revenue = enterprise_value / total_revenue

        return {
            'Ticker': ticker_symbol,
            'Company': company_name,
            'Current_Price': current_price,
            'Market_Cap': market_cap,
            'Enterprise_Value': enterprise_value,
            'LTM_Revenue': total_revenue,
            'Revenue_Growth': revenue_growth,
            'EV_Revenue_Multiple': ev_revenue,
            'Forward_PE': forward_pe,
            'Earnings_Growth': earnings_growth,
            'Sector': info.get('sector'),
            'Industry': info.get('industry'),
            'Data_Timestamp': datetime.now().isoformat()
        }

    except Exception as e:
        print(f"    Error fetching {ticker_symbol}: {e}")
        return {
            'Ticker': ticker_symbol,
            'Company': company_name,
            'Current_Price': None,
            'Market_Cap': None,
            'Enterprise_Value': None,
            'LTM_Revenue': None,
            'Revenue_Growth': None,
            'EV_Revenue_Multiple': None,
            'Forward_PE': None,
            'Earnings_Growth': None,
            'Sector': None,
            'Industry': None,
            'Data_Timestamp': datetime.now().isoformat(),
            'Error': str(e)
        }


def apply_screening_criteria(df):
    """
    Apply M&A screening criteria to the dataset.

    Parameters
    ----------
    df : pd.DataFrame
        Financial data for all targets

    Returns
    -------
    pd.DataFrame
        DataFrame with screening results added
    """
    print("\n  Applying screening criteria...")

    # Market Cap criteria: $2B - $15B
    df['MarketCap_Pass'] = df['Market_Cap'].apply(
        lambda x: MARKET_CAP_MIN <= x <= MARKET_CAP_MAX if pd.notna(x) else False
    )

    # Revenue Growth criteria: > 20%
    df['RevenueGrowth_Pass'] = df['Revenue_Growth'].apply(
        lambda x: x > REVENUE_GROWTH_MIN if pd.notna(x) else False
    )

    # Overall pass (both criteria)
    df['Overall_Pass'] = df['MarketCap_Pass'] & df['RevenueGrowth_Pass']

    return df


def generate_screening_summary(df):
    """
    Generate a markdown summary of the screening results.

    Parameters
    ----------
    df : pd.DataFrame
        Financial data with screening results

    Returns
    -------
    str
        Markdown formatted summary
    """
    summary_lines = [
        "# M&A Target Screening Summary",
        "",
        f"**Date**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
        "",
        "## Screening Criteria",
        "",
        f"- **Market Cap Range**: $2B - $15B",
        f"- **Revenue Growth**: > 20% (YoY)",
        "",
        "## Results Overview",
        "",
        f"- **Total Targets Analyzed**: {len(df)}",
        f"- **Targets Passing All Criteria**: {df['Overall_Pass'].sum()}",
        f"- **Targets Failing**: {(~df['Overall_Pass']).sum()}",
        "",
        "## Detailed Results",
        "",
        "| Company | Ticker | Market Cap | Revenue Growth | EV/Revenue | Market Cap Pass | Growth Pass | Overall |",
        "|---------|--------|------------|----------------|------------|-----------------|-------------|---------|"
    ]

    for _, row in df.iterrows():
        mc_formatted = format_billions(row['Market_Cap'])
        rg_formatted = format_percentage(row['Revenue_Growth'])
        ev_rev = f"{row['EV_Revenue_Multiple']:.1f}x" if pd.notna(row['EV_Revenue_Multiple']) else "N/A"
        mc_pass = "PASS" if row['MarketCap_Pass'] else "FAIL"
        rg_pass = "PASS" if row['RevenueGrowth_Pass'] else "FAIL"
        overall = "PASS" if row['Overall_Pass'] else "FAIL"

        summary_lines.append(
            f"| {row['Company']} | {row['Ticker']} | {mc_formatted} | {rg_formatted} | "
            f"{ev_rev} | {mc_pass} | {rg_pass} | **{overall}** |"
        )

    summary_lines.extend([
        "",
        "## Individual Analysis",
        ""
    ])

    for _, row in df.iterrows():
        summary_lines.extend([
            f"### {row['Company']} ({row['Ticker']})",
            "",
            f"- **Current Price**: ${row['Current_Price']:.2f}" if pd.notna(row['Current_Price']) else "- **Current Price**: N/A",
            f"- **Market Cap**: {format_billions(row['Market_Cap'])}",
            f"- **Enterprise Value**: {format_billions(row['Enterprise_Value'])}",
            f"- **LTM Revenue**: {format_billions(row['LTM_Revenue'])}",
            f"- **Revenue Growth (YoY)**: {format_percentage(row['Revenue_Growth'])}",
            f"- **EV/Revenue Multiple**: {row['EV_Revenue_Multiple']:.2f}x" if pd.notna(row['EV_Revenue_Multiple']) else "- **EV/Revenue Multiple**: N/A",
            ""
        ])

        # Analysis notes
        notes = []
        if not row['MarketCap_Pass']:
            mc = row['Market_Cap']
            if pd.notna(mc):
                if mc < MARKET_CAP_MIN:
                    notes.append(f"Market cap below minimum threshold (${mc/1e9:.1f}B < $2B)")
                else:
                    notes.append(f"Market cap above maximum threshold (${mc/1e9:.1f}B > $15B)")

        if not row['RevenueGrowth_Pass']:
            rg = row['Revenue_Growth']
            if pd.notna(rg):
                notes.append(f"Revenue growth below threshold ({rg*100:.1f}% < 20%)")
            else:
                notes.append("Revenue growth data not available")

        if notes:
            summary_lines.append(f"**Notes**: {'; '.join(notes)}")
            summary_lines.append("")
        elif row['Overall_Pass']:
            summary_lines.append("**Status**: Meets all screening criteria - potential acquisition target")
            summary_lines.append("")

    summary_lines.extend([
        "---",
        "",
        "*Generated by K-Dense M&A Target Screening Tool*"
    ])

    return "\n".join(summary_lines)


def main():
    """Main execution function."""
    print("=" * 60)
    print("M&A TARGET FINANCIAL SCREENING")
    print("Cybersecurity Sector Analysis")
    print("=" * 60)
    print(f"\nTimestamp: {datetime.now().isoformat()}")
    print(f"\nTargets: {', '.join([f'{v} ({k})' for k, v in TARGETS.items()])}")
    print("\nScreening Criteria:")
    print(f"  - Market Cap: ${MARKET_CAP_MIN/1e9:.0f}B - ${MARKET_CAP_MAX/1e9:.0f}B")
    print(f"  - Revenue Growth: > {REVENUE_GROWTH_MIN*100:.0f}%")

    # Fetch financial data
    print("\n" + "-" * 40)
    print("STEP 1: Fetching Financial Data")
    print("-" * 40)

    results = []
    total = len(TARGETS)
    for i, (ticker, company) in enumerate(TARGETS.items(), 1):
        print(f"\nProgress: {i}/{total}")
        data = fetch_financial_data(ticker, company)
        results.append(data)

    # Create DataFrame
    df = pd.DataFrame(results)

    # Apply screening criteria
    print("\n" + "-" * 40)
    print("STEP 2: Applying Screening Criteria")
    print("-" * 40)
    df = apply_screening_criteria(df)

    # Save raw financial data
    print("\n" + "-" * 40)
    print("STEP 3: Saving Results")
    print("-" * 40)

    csv_path = f"{RESULTS_DIR}/financial_screening_data.csv"
    df.to_csv(csv_path, index=False)
    print(f"  Saved: {csv_path}")

    # Generate and save summary
    summary_md = generate_screening_summary(df)
    summary_path = f"{RESULTS_DIR}/screening_summary.md"
    with open(summary_path, 'w') as f:
        f.write(summary_md)
    print(f"  Saved: {summary_path}")

    # Print summary to console
    print("\n" + "=" * 60)
    print("SCREENING RESULTS SUMMARY")
    print("=" * 60)

    passed = df[df['Overall_Pass']]
    failed = df[~df['Overall_Pass']]

    print(f"\nTargets PASSING all criteria ({len(passed)}):")
    for _, row in passed.iterrows():
        print(f"  - {row['Company']} ({row['Ticker']}): "
              f"MC={format_billions(row['Market_Cap'])}, "
              f"Growth={format_percentage(row['Revenue_Growth'])}")

    print(f"\nTargets FAILING criteria ({len(failed)}):")
    for _, row in failed.iterrows():
        reasons = []
        if not row['MarketCap_Pass']:
            reasons.append("Market Cap")
        if not row['RevenueGrowth_Pass']:
            reasons.append("Revenue Growth")
        print(f"  - {row['Company']} ({row['Ticker']}): Failed {', '.join(reasons)}")

    print("\n" + "=" * 60)
    print("EXECUTION COMPLETE")
    print("=" * 60)

    return df


if __name__ == "__main__":
    main()
