#!/usr/bin/env python3
"""
Step 3: Valuation, Subscriber Decay Modeling & Technical Analysis
================================================================
Constructs quantitative models to project future revenue/subscriber decline scenarios,
performs valuation analysis (DCF/Reverse DCF) to establish price targets, and
analyzes technical market indicators.
"""

import pandas as pd
import numpy as np
import json
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from pathlib import Path
from datetime import datetime, timedelta

# Set paths
BASE_DIR = Path("/app/sandbox/session_20260203_085912_030e6e80a419")
DATA_DIR = BASE_DIR / "data"
RESULTS_DIR = BASE_DIR / "results"
FIGURES_DIR = BASE_DIR / "figures"

# Set random seed for reproducibility
np.random.seed(42)

# Set matplotlib backend and style
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.size'] = 10
plt.rcParams['axes.linewidth'] = 0.5
plt.rcParams['figure.facecolor'] = 'white'

print("=" * 70)
print("Step 3: Valuation, Subscriber Decay Modeling & Technical Analysis")
print("=" * 70)

# =============================================================================
# 1. Load Data
# =============================================================================
print("\n[1/5] Loading data...")

# Load financial metrics history
financial_df = pd.read_csv(RESULTS_DIR / "financial_metrics_history.csv")
financial_df['Date'] = pd.to_datetime(financial_df['Date'])
print(f"  - Loaded financial metrics: {len(financial_df)} years of data")
print(f"  - Revenue range: ${financial_df['Total_Revenue'].min()/1e6:.0f}M - ${financial_df['Total_Revenue'].max()/1e6:.0f}M")

# Load key stats
with open(DATA_DIR / "chgg_key_stats.json", 'r') as f:
    key_stats = json.load(f)
print(f"  - Loaded key stats: Market Cap ${key_stats['marketCap']/1e6:.1f}M")

# Load market data
market_df = pd.read_csv(DATA_DIR / "chgg_market_data.csv")
market_df['Date'] = pd.to_datetime(market_df['Date'].str.split(' ').str[0])
market_df = market_df.sort_values('Date').reset_index(drop=True)
print(f"  - Loaded market data: {len(market_df)} trading days")
print(f"  - Price range: ${market_df['Close'].min():.2f} - ${market_df['Close'].max():.2f}")

# Extract key current metrics
current_price = key_stats['marketCap'] / key_stats['sharesOutstanding']
shares_outstanding = key_stats['sharesOutstanding']
total_cash = key_stats['totalCash']
total_debt = key_stats['totalDebt']
book_value_per_share = key_stats['bookValue']
ttm_revenue = key_stats['totalRevenue']
ttm_fcf = key_stats['freeCashflow']

print(f"\n  Current Metrics:")
print(f"  - Current Price: ${current_price:.2f}")
print(f"  - Shares Outstanding: {shares_outstanding/1e6:.1f}M")
print(f"  - Cash: ${total_cash/1e6:.1f}M, Debt: ${total_debt/1e6:.1f}M")
print(f"  - TTM Revenue: ${ttm_revenue/1e6:.1f}M")
print(f"  - TTM FCF: ${ttm_fcf/1e6:.1f}M")

# =============================================================================
# 2. Revenue & Subscriber Decay Modeling
# =============================================================================
print("\n[2/5] Building Revenue Decay Models...")

# Calculate historical decline rates
financial_df_sorted = financial_df.sort_values('Date')
revenue_history = financial_df_sorted[['Date', 'Total_Revenue', 'Revenue_YoY_Growth']].copy()
revenue_history['Year'] = revenue_history['Date'].dt.year

# Calculate compound annual decline rate
first_year_rev = revenue_history['Total_Revenue'].iloc[0]
last_year_rev = revenue_history['Total_Revenue'].iloc[-1]
num_years = len(revenue_history) - 1
cagr = (last_year_rev / first_year_rev) ** (1/num_years) - 1
print(f"  - Historical CAGR (2021-2024): {cagr*100:.1f}%")

# Recent decline rate (latest year)
recent_decline = revenue_history['Revenue_YoY_Growth'].iloc[-1] / 100
print(f"  - Latest YoY decline (2024): {recent_decline*100:.1f}%")

# Use TTM vs 2024 annual to get most recent trend
if ttm_revenue < last_year_rev:
    current_run_rate_decline = (ttm_revenue / last_year_rev) - 1
    print(f"  - TTM vs 2024 Annual implied decline: {current_run_rate_decline*100:.1f}%")
else:
    current_run_rate_decline = recent_decline

# Define scenarios
scenarios = {
    'Bull Case': {
        'description': 'Stabilization - AI disruption slows, management executes turnaround',
        'growth_rates': [-0.05, -0.03, 0.0, 0.0, 0.02],  # Stabilizing to flat/slight growth
        'fcf_margin': 0.08,  # Improving margins
        'terminal_growth': 0.0,
        'probability': 0.15
    },
    'Base Case': {
        'description': 'Continued decline - Current trajectory persists',
        'growth_rates': [-0.18, -0.18, -0.15, -0.12, -0.10],  # Gradually slowing decline
        'fcf_margin': 0.05,  # Margin compression continues
        'terminal_growth': -0.05,
        'probability': 0.50
    },
    'Bear Case': {
        'description': 'Accelerated AI disruption - ChatGPT/AI kills demand faster',
        'growth_rates': [-0.30, -0.35, -0.30, -0.25, -0.20],  # Accelerated decline
        'fcf_margin': 0.0,  # Margins collapse to breakeven
        'terminal_growth': -0.10,
        'probability': 0.35
    }
}

# Project revenue for next 5 years
projection_years = [2025, 2026, 2027, 2028, 2029]
base_revenue = ttm_revenue  # Use TTM as starting point

projections = {}
for scenario_name, params in scenarios.items():
    print(f"\n  {scenario_name}:")
    print(f"    {params['description']}")

    revenues = [base_revenue]
    for i, growth in enumerate(params['growth_rates']):
        next_rev = revenues[-1] * (1 + growth)
        revenues.append(next_rev)
        print(f"    {projection_years[i]}: ${next_rev/1e6:.1f}M ({growth*100:+.0f}%)")

    # Calculate projected FCF
    fcf_projections = [rev * params['fcf_margin'] for rev in revenues[1:]]

    projections[scenario_name] = {
        'revenues': revenues[1:],  # Exclude base year
        'growth_rates': params['growth_rates'],
        'fcf_projections': fcf_projections,
        'fcf_margin': params['fcf_margin'],
        'terminal_growth': params['terminal_growth'],
        'probability': params['probability']
    }

# Create projection dataframe for saving
projection_data = []
for year in projection_years:
    row = {'Year': year}
    for scenario_name in ['Bull Case', 'Base Case', 'Bear Case']:
        idx = projection_years.index(year)
        row[f'{scenario_name}_Revenue'] = projections[scenario_name]['revenues'][idx]
        row[f'{scenario_name}_FCF'] = projections[scenario_name]['fcf_projections'][idx]
    projection_data.append(row)

projection_df = pd.DataFrame(projection_data)
print("\n  Revenue Projections (Millions):")
print(projection_df.to_string(index=False))

# =============================================================================
# 3. Valuation Analysis
# =============================================================================
print("\n[3/5] Performing Valuation Analysis...")

# DCF Parameters
WACC = 0.11  # 11% - elevated for distressed company
TAX_RATE = 0.21

def calculate_dcf(fcf_projections, terminal_growth, wacc, terminal_year_fcf):
    """Calculate DCF value"""
    # Present value of projection period FCFs
    pv_fcfs = sum(fcf / (1 + wacc) ** (i + 1) for i, fcf in enumerate(fcf_projections))

    # Terminal value using perpetuity growth model
    if wacc > terminal_growth:
        terminal_value = terminal_year_fcf * (1 + terminal_growth) / (wacc - terminal_growth)
    else:
        terminal_value = 0  # Model breaks if growth >= wacc

    # Present value of terminal value
    n_years = len(fcf_projections)
    pv_terminal = terminal_value / (1 + wacc) ** n_years

    # Enterprise value
    enterprise_value = pv_fcfs + pv_terminal

    return {
        'pv_fcfs': pv_fcfs,
        'terminal_value': terminal_value,
        'pv_terminal': pv_terminal,
        'enterprise_value': enterprise_value
    }

# Calculate DCF for each scenario
dcf_results = {}
print(f"\n  DCF Valuation (WACC = {WACC*100:.0f}%):")
print("-" * 60)

for scenario_name, proj in projections.items():
    dcf = calculate_dcf(
        proj['fcf_projections'],
        proj['terminal_growth'],
        WACC,
        proj['fcf_projections'][-1]
    )

    # Calculate equity value
    equity_value = dcf['enterprise_value'] + total_cash - total_debt
    if equity_value < 0:
        equity_value = 0  # Floor at zero

    fair_value_per_share = equity_value / shares_outstanding

    dcf_results[scenario_name] = {
        'enterprise_value': dcf['enterprise_value'],
        'equity_value': equity_value,
        'fair_value_per_share': fair_value_per_share,
        'pv_fcfs': dcf['pv_fcfs'],
        'terminal_value': dcf['terminal_value'],
        'pv_terminal': dcf['pv_terminal'],
        'upside': (fair_value_per_share / current_price - 1) * 100 if current_price > 0 else 0
    }

    print(f"\n  {scenario_name}:")
    print(f"    PV of FCFs (5yr):     ${dcf['pv_fcfs']/1e6:>8.1f}M")
    print(f"    Terminal Value:       ${dcf['terminal_value']/1e6:>8.1f}M")
    print(f"    PV of Terminal:       ${dcf['pv_terminal']/1e6:>8.1f}M")
    print(f"    Enterprise Value:     ${dcf['enterprise_value']/1e6:>8.1f}M")
    print(f"    + Cash - Debt:        ${(total_cash - total_debt)/1e6:>8.1f}M")
    print(f"    Equity Value:         ${equity_value/1e6:>8.1f}M")
    print(f"    Fair Value/Share:     ${fair_value_per_share:>8.2f}")
    print(f"    vs Current ({current_price:.2f}):    {dcf_results[scenario_name]['upside']:>+7.0f}%")

# Probability-Weighted Fair Value
weighted_fv = sum(
    dcf_results[s]['fair_value_per_share'] * projections[s]['probability']
    for s in projections.keys()
)
print(f"\n  Probability-Weighted Fair Value: ${weighted_fv:.2f}")
print(f"  (Bull 15%, Base 50%, Bear 35%)")

# Reverse DCF Analysis
print("\n  Reverse DCF Analysis:")
print("-" * 60)
print("  What growth rate is implied by current stock price?")

# Solve for implied growth rate
# Current market cap implies EV = market_cap - cash + debt
current_ev = key_stats['marketCap'] - total_cash + total_debt
print(f"  Current Enterprise Value: ${current_ev/1e6:.1f}M")

# If we assume perpetuity model: EV = FCF * (1+g) / (WACC - g)
# Solving for g: g = (EV * WACC - FCF) / (EV + FCF)
implied_growth = (current_ev * WACC - ttm_fcf) / (current_ev + ttm_fcf)
print(f"  Using TTM FCF (${ttm_fcf/1e6:.1f}M) and WACC ({WACC*100:.0f}%):")
print(f"  Implied Perpetual Growth Rate: {implied_growth*100:.1f}%")

# What the market is pricing in
if implied_growth < -0.50:
    market_expectation = "Market pricing in severe/complete business destruction"
elif implied_growth < -0.20:
    market_expectation = "Market pricing in accelerated decline (Bear case)"
elif implied_growth < -0.05:
    market_expectation = "Market pricing in continued decline (Base case)"
else:
    market_expectation = "Market pricing in stabilization (Bull case)"

print(f"  Interpretation: {market_expectation}")

# Liquidation Value Analysis
print("\n  Liquidation Value Analysis:")
print("-" * 60)

# Load balance sheet for more detailed asset breakdown
balance_sheet = pd.read_csv(DATA_DIR / "chgg_balance_sheet_annual.csv")
latest_bs = balance_sheet.iloc[0]  # Most recent year

# Current assets are usually more liquid
# We discount different asset types at different rates
current_assets = key_stats.get('currentRatio', 1.0) * total_debt  # Estimate if not available
if 'Total Current Assets' in latest_bs.index:
    current_assets = latest_bs['Total Current Assets']

# Conservative liquidation estimates
liquidation_items = {
    'Cash': (total_cash, 1.0),  # Full value
    'A/R & Other Current': (50_000_000, 0.7),  # 70% recovery estimate
    'PP&E': (30_000_000, 0.2),  # 20% of book - distressed sale
    'Intangibles/Goodwill': (0, 0.0),  # Zero recovery on goodwill
}

total_liquidation = sum(amount * recovery for amount, recovery in liquidation_items.values())
liquidation_less_debt = total_liquidation - total_debt
liquidation_per_share = max(0, liquidation_less_debt) / shares_outstanding

print(f"  Cash (100% recovery):           ${total_cash/1e6:>6.1f}M")
print(f"  Other Current Assets (70%):     ${50*0.7:>6.1f}M (estimated)")
print(f"  PP&E (20% distressed):          ${30*0.2:>6.1f}M (estimated)")
print(f"  Goodwill/Intangibles (0%):      $  0.0M")
print(f"  ----------------------------------------")
print(f"  Total Liquidation Value:        ${total_liquidation/1e6:>6.1f}M")
print(f"  Less: Total Debt                ${total_debt/1e6:>6.1f}M")
print(f"  ----------------------------------------")
print(f"  Net Liquidation Value:          ${liquidation_less_debt/1e6:>6.1f}M")
print(f"  Liquidation Value/Share:        ${liquidation_per_share:>6.2f}")
print(f"  vs Current Price:               {((liquidation_per_share/current_price - 1)*100):>+6.0f}%" if current_price > 0 else "N/A")

# Book Value comparison
print(f"\n  Book Value Comparison:")
print(f"  Book Value/Share (reported):    ${book_value_per_share:.2f}")
print(f"  Price/Book Ratio:               {current_price/book_value_per_share:.2f}x")
print(f"  Discount to Book:               {(1 - current_price/book_value_per_share)*100:.0f}%")

# =============================================================================
# 4. Technical Analysis
# =============================================================================
print("\n[4/5] Performing Technical Analysis...")

# Calculate technical indicators
def calculate_sma(series, window):
    """Calculate Simple Moving Average"""
    return series.rolling(window=window, min_periods=1).mean()

def calculate_rsi(series, window=14):
    """Calculate Relative Strength Index"""
    delta = series.diff()
    gain = (delta.where(delta > 0, 0)).rolling(window=window).mean()
    loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean()
    rs = gain / loss
    rsi = 100 - (100 / (1 + rs))
    return rsi

# Add technical indicators to market data
market_df['SMA_50'] = calculate_sma(market_df['Close'], 50)
market_df['SMA_200'] = calculate_sma(market_df['Close'], 200)
market_df['RSI'] = calculate_rsi(market_df['Close'], 14)
market_df['Volume_SMA_20'] = calculate_sma(market_df['Volume'], 20)

# Get latest values
latest_data = market_df.iloc[-1]
latest_price = latest_data['Close']
latest_sma50 = latest_data['SMA_50']
latest_sma200 = latest_data['SMA_200']
latest_rsi = latest_data['RSI']
latest_volume = latest_data['Volume']
avg_volume = latest_data['Volume_SMA_20']

print(f"\n  Latest Technical Indicators:")
print(f"  - Price: ${latest_price:.2f}")
print(f"  - 50-day SMA: ${latest_sma50:.2f} ({((latest_price/latest_sma50 - 1)*100):+.1f}% vs price)")
print(f"  - 200-day SMA: ${latest_sma200:.2f} ({((latest_price/latest_sma200 - 1)*100):+.1f}% vs price)")
print(f"  - RSI (14-day): {latest_rsi:.1f}")

# RSI interpretation
if latest_rsi < 30:
    rsi_signal = "OVERSOLD - potential bounce"
elif latest_rsi > 70:
    rsi_signal = "OVERBOUGHT - potential pullback"
else:
    rsi_signal = "NEUTRAL"
print(f"  - RSI Signal: {rsi_signal}")

# Trend analysis
if latest_price < latest_sma50 < latest_sma200:
    trend = "STRONG DOWNTREND - Price below both SMAs, death cross"
elif latest_price < latest_sma50:
    trend = "DOWNTREND - Price below 50 SMA"
elif latest_price > latest_sma50 > latest_sma200:
    trend = "STRONG UPTREND - Price above both SMAs, golden cross"
else:
    trend = "MIXED/TRANSITIONAL"
print(f"  - Trend: {trend}")

# Volume analysis
recent_avg_volume = market_df['Volume'].tail(20).mean()
older_avg_volume = market_df['Volume'].tail(60).head(40).mean()
volume_trend = (recent_avg_volume / older_avg_volume - 1) * 100

print(f"\n  Volume Analysis:")
print(f"  - 20-day Avg Volume: {recent_avg_volume/1e6:.2f}M shares")
print(f"  - 60-day Avg Volume: {older_avg_volume/1e6:.2f}M shares")
print(f"  - Volume Trend: {volume_trend:+.1f}%")

if volume_trend > 20:
    volume_signal = "INCREASING VOLUME - selling/buying pressure intensifying"
elif volume_trend < -20:
    volume_signal = "DECREASING VOLUME - interest waning, potential bottom formation"
else:
    volume_signal = "STABLE VOLUME"
print(f"  - Volume Signal: {volume_signal}")

# Support/Resistance levels
# Find recent highs and lows
recent_90d = market_df.tail(90)
recent_high = recent_90d['High'].max()
recent_low = recent_90d['Low'].min()
year_high = market_df.tail(252)['High'].max() if len(market_df) >= 252 else market_df['High'].max()
year_low = market_df.tail(252)['Low'].min() if len(market_df) >= 252 else market_df['Low'].min()

print(f"\n  Support/Resistance Levels:")
print(f"  - 52-week High: ${year_high:.2f}")
print(f"  - 52-week Low: ${year_low:.2f}")
print(f"  - 90-day High: ${recent_high:.2f}")
print(f"  - 90-day Low: ${recent_low:.2f}")
print(f"  - Key Support: ${year_low:.2f}")
print(f"  - Key Resistance: ${latest_sma50:.2f} (50 SMA)")

# Save technical indicators
tech_indicators = {
    'Date': latest_data['Date'].strftime('%Y-%m-%d') if hasattr(latest_data['Date'], 'strftime') else str(latest_data['Date']),
    'Price': latest_price,
    'SMA_50': latest_sma50,
    'SMA_200': latest_sma200,
    'RSI_14': latest_rsi,
    'RSI_Signal': rsi_signal,
    'Trend': trend,
    'Volume_20d_Avg': recent_avg_volume,
    'Volume_60d_Avg': older_avg_volume,
    'Volume_Trend_Pct': volume_trend,
    'Volume_Signal': volume_signal,
    '52_Week_High': year_high,
    '52_Week_Low': year_low,
    '90_Day_High': recent_high,
    '90_Day_Low': recent_low
}

tech_df = pd.DataFrame([tech_indicators])
tech_df.to_csv(RESULTS_DIR / "technical_indicators.csv", index=False)
print(f"\n  Saved: results/technical_indicators.csv")

# =============================================================================
# 5. Visualizations
# =============================================================================
print("\n[5/5] Creating Visualizations...")

# Figure 1: Revenue Projection Scenarios
print("  Creating projected_revenue_scenarios.png...")
fig, ax = plt.subplots(figsize=(12, 7))

# Historical data
hist_years = financial_df_sorted['Date'].dt.year.tolist()
hist_revenues = (financial_df_sorted['Total_Revenue'] / 1e6).tolist()

# Add TTM as 2025 estimate
all_years_hist = hist_years + [2024.5]  # TTM point
all_revenues_hist = hist_revenues + [ttm_revenue / 1e6]

# Plot historical
ax.plot(hist_years, hist_revenues, 'ko-', linewidth=2, markersize=8, label='Historical', zorder=5)
ax.plot([2024, 2024.5], [hist_revenues[-1], ttm_revenue/1e6], 'k--', linewidth=1.5, alpha=0.7)
ax.scatter([2024.5], [ttm_revenue/1e6], color='black', s=60, marker='s', zorder=5, label='TTM')

# Plot scenarios
colors = {'Bull Case': '#2ecc71', 'Base Case': '#3498db', 'Bear Case': '#e74c3c'}
linestyles = {'Bull Case': '-', 'Base Case': '-', 'Bear Case': '-'}

for scenario_name in ['Bear Case', 'Base Case', 'Bull Case']:
    proj = projections[scenario_name]
    proj_years = projection_years
    proj_revenues = [r / 1e6 for r in proj['revenues']]

    # Connect from TTM to first projection
    ax.plot([2024.5] + proj_years, [ttm_revenue/1e6] + proj_revenues,
            color=colors[scenario_name], linestyle=linestyles[scenario_name],
            linewidth=2.5, marker='o', markersize=6,
            label=f'{scenario_name} ({proj["probability"]*100:.0f}%)')

# Add annotations
ax.axhline(y=100, color='gray', linestyle=':', alpha=0.5, label='$100M threshold')

# Formatting
ax.set_xlabel('Year', fontsize=12)
ax.set_ylabel('Revenue ($ Millions)', fontsize=12)
ax.set_title('Chegg Revenue Projections: The Subscriber Cliff\n3 Scenarios for AI-Disrupted EdTech', fontsize=14, fontweight='bold')
ax.legend(loc='upper right', fontsize=10)
ax.grid(True, alpha=0.3)
ax.set_xlim(2020.5, 2030)
ax.set_ylim(0, 850)

# Add text annotations
peak_rev = max(hist_revenues)
ax.annotate(f'Peak: ${peak_rev:.0f}M', xy=(2021, peak_rev), xytext=(2021, peak_rev+50),
            fontsize=9, ha='center')

# Add scenario endpoint labels
for scenario_name in ['Bear Case', 'Base Case', 'Bull Case']:
    final_rev = projections[scenario_name]['revenues'][-1] / 1e6
    y_offset = {'Bull Case': 20, 'Base Case': 0, 'Bear Case': -20}[scenario_name]
    ax.annotate(f'${final_rev:.0f}M', xy=(2029, final_rev), xytext=(2029.3, final_rev + y_offset),
                fontsize=9, color=colors[scenario_name], fontweight='bold')

plt.tight_layout()
plt.savefig(FIGURES_DIR / "projected_revenue_scenarios.png", dpi=300, bbox_inches='tight')
plt.close()
print("    Saved: figures/projected_revenue_scenarios.png")

# Figure 2: Valuation Sensitivity
print("  Creating valuation_sensitivity.png...")
fig, ax = plt.subplots(figsize=(10, 7))

# Data for bar chart
scenarios_list = ['Bear Case', 'Base Case', 'Bull Case', 'Liquidation', 'Book Value']
fair_values = [
    dcf_results['Bear Case']['fair_value_per_share'],
    dcf_results['Base Case']['fair_value_per_share'],
    dcf_results['Bull Case']['fair_value_per_share'],
    liquidation_per_share,
    book_value_per_share
]
bar_colors = ['#e74c3c', '#3498db', '#2ecc71', '#95a5a6', '#9b59b6']

x = np.arange(len(scenarios_list))
bars = ax.bar(x, fair_values, color=bar_colors, edgecolor='black', linewidth=1)

# Add current price line
ax.axhline(y=current_price, color='black', linestyle='--', linewidth=2, label=f'Current Price: ${current_price:.2f}')

# Add value labels on bars
for i, (bar, val) in enumerate(zip(bars, fair_values)):
    height = bar.get_height()
    ax.annotate(f'${val:.2f}',
                xy=(bar.get_x() + bar.get_width() / 2, height),
                xytext=(0, 5),
                textcoords="offset points",
                ha='center', va='bottom', fontsize=11, fontweight='bold')

# Add upside/downside labels
for i, (scenario, val) in enumerate(zip(scenarios_list, fair_values)):
    if current_price > 0:
        pct_change = (val / current_price - 1) * 100
        color = '#2ecc71' if pct_change > 0 else '#e74c3c'
        ax.annotate(f'{pct_change:+.0f}%',
                    xy=(i, val),
                    xytext=(0, 20),
                    textcoords="offset points",
                    ha='center', va='bottom', fontsize=10, color=color, fontweight='bold')

ax.set_xticks(x)
ax.set_xticklabels(scenarios_list, fontsize=11)
ax.set_ylabel('Fair Value per Share ($)', fontsize=12)
ax.set_title('Chegg Valuation Analysis: Fair Value vs Current Price\nDCF, Liquidation, and Book Value Comparison', fontsize=14, fontweight='bold')
ax.legend(loc='upper right', fontsize=11)
ax.grid(axis='y', alpha=0.3)
ax.set_ylim(0, max(fair_values) * 1.4)

# Add probability-weighted annotation
ax.annotate(f'Probability-Weighted Fair Value: ${weighted_fv:.2f}',
            xy=(0.5, 0.95), xycoords='axes fraction',
            ha='center', fontsize=11,
            bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))

plt.tight_layout()
plt.savefig(FIGURES_DIR / "valuation_sensitivity.png", dpi=300, bbox_inches='tight')
plt.close()
print("    Saved: figures/valuation_sensitivity.png")

# Figure 3: Technical Chart
print("  Creating technical_chart.png...")
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(14, 10), gridspec_kw={'height_ratios': [3, 1, 1]})

# Use last 252 trading days (1 year) for technical chart
tech_data = market_df.tail(252).copy()

# Price chart with SMAs
ax1.plot(tech_data['Date'], tech_data['Close'], 'b-', linewidth=1.5, label='Price', alpha=0.8)
ax1.plot(tech_data['Date'], tech_data['SMA_50'], 'orange', linewidth=1.5, label='50-day SMA', alpha=0.8)
ax1.plot(tech_data['Date'], tech_data['SMA_200'], 'red', linewidth=1.5, label='200-day SMA', alpha=0.8)

# Shade between SMAs to show trend
ax1.fill_between(tech_data['Date'], tech_data['SMA_50'], tech_data['SMA_200'],
                 where=tech_data['SMA_50'] >= tech_data['SMA_200'],
                 facecolor='green', alpha=0.1, interpolate=True)
ax1.fill_between(tech_data['Date'], tech_data['SMA_50'], tech_data['SMA_200'],
                 where=tech_data['SMA_50'] < tech_data['SMA_200'],
                 facecolor='red', alpha=0.1, interpolate=True)

ax1.set_ylabel('Price ($)', fontsize=11)
ax1.set_title('Chegg (CHGG) Technical Analysis - 1 Year', fontsize=14, fontweight='bold')
ax1.legend(loc='upper right', fontsize=10)
ax1.grid(True, alpha=0.3)
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))

# Volume chart
colors_vol = ['red' if tech_data['Close'].iloc[i] < tech_data['Close'].iloc[i-1] else 'green'
              for i in range(1, len(tech_data))]
colors_vol = ['green'] + colors_vol  # First bar

ax2.bar(tech_data['Date'], tech_data['Volume'] / 1e6, color=colors_vol, alpha=0.7, width=1)
ax2.plot(tech_data['Date'], tech_data['Volume_SMA_20'] / 1e6, 'orange', linewidth=1.5, label='20-day Avg')
ax2.set_ylabel('Volume (M)', fontsize=11)
ax2.legend(loc='upper right', fontsize=10)
ax2.grid(True, alpha=0.3)
ax2.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))

# RSI chart
ax3.plot(tech_data['Date'], tech_data['RSI'], 'purple', linewidth=1.5)
ax3.axhline(y=70, color='red', linestyle='--', alpha=0.7, label='Overbought (70)')
ax3.axhline(y=30, color='green', linestyle='--', alpha=0.7, label='Oversold (30)')
ax3.fill_between(tech_data['Date'], 30, tech_data['RSI'], where=tech_data['RSI'] < 30,
                 facecolor='green', alpha=0.3)
ax3.fill_between(tech_data['Date'], 70, tech_data['RSI'], where=tech_data['RSI'] > 70,
                 facecolor='red', alpha=0.3)
ax3.set_ylabel('RSI', fontsize=11)
ax3.set_xlabel('Date', fontsize=11)
ax3.set_ylim(0, 100)
ax3.legend(loc='upper right', fontsize=10)
ax3.grid(True, alpha=0.3)
ax3.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))

plt.tight_layout()
plt.savefig(FIGURES_DIR / "technical_chart.png", dpi=300, bbox_inches='tight')
plt.close()
print("    Saved: figures/technical_chart.png")

# =============================================================================
# 6. Save Results
# =============================================================================
print("\n[6/5] Saving Results...")

# Save projection scenarios
projection_df.to_csv(RESULTS_DIR / "valuation_scenarios.csv", index=False)
print(f"  Saved: results/valuation_scenarios.csv")

# Generate comprehensive valuation summary
summary_text = f"""
================================================================================
CHEGG (CHGG) VALUATION ANALYSIS SUMMARY
Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
================================================================================

CURRENT MARKET DATA
-------------------
Current Price:          ${current_price:.2f}
Market Cap:             ${key_stats['marketCap']/1e6:.1f}M
Shares Outstanding:     {shares_outstanding/1e6:.1f}M
52-Week Range:          ${year_low:.2f} - ${year_high:.2f}
Book Value/Share:       ${book_value_per_share:.2f}
Price/Book:             {current_price/book_value_per_share:.2f}x

FINANCIAL SNAPSHOT (TTM)
------------------------
Revenue:                ${ttm_revenue/1e6:.1f}M
Free Cash Flow:         ${ttm_fcf/1e6:.1f}M
Cash:                   ${total_cash/1e6:.1f}M
Debt:                   ${total_debt/1e6:.1f}M
Net Cash Position:      ${(total_cash - total_debt)/1e6:.1f}M

HISTORICAL REVENUE DECLINE
--------------------------
2021: ${hist_revenues[0]:.0f}M
2022: ${hist_revenues[1]:.0f}M ({((hist_revenues[1]/hist_revenues[0])-1)*100:+.1f}%)
2023: ${hist_revenues[2]:.0f}M ({((hist_revenues[2]/hist_revenues[1])-1)*100:+.1f}%)
2024: ${hist_revenues[3]:.0f}M ({((hist_revenues[3]/hist_revenues[2])-1)*100:+.1f}%)
TTM:  ${ttm_revenue/1e6:.0f}M ({((ttm_revenue/1e6/hist_revenues[3])-1)*100:+.1f}%)
3-Year CAGR: {cagr*100:.1f}%

DCF VALUATION (WACC = {WACC*100:.0f}%)
------------------------------------

BULL CASE (15% probability) - Stabilization Scenario
  Revenue 2029E:        ${projections['Bull Case']['revenues'][-1]/1e6:.0f}M
  FCF Margin:           {projections['Bull Case']['fcf_margin']*100:.0f}%
  Terminal Growth:      {projections['Bull Case']['terminal_growth']*100:.0f}%
  Enterprise Value:     ${dcf_results['Bull Case']['enterprise_value']/1e6:.1f}M
  Fair Value/Share:     ${dcf_results['Bull Case']['fair_value_per_share']:.2f}
  Upside vs Current:    {dcf_results['Bull Case']['upside']:+.0f}%

BASE CASE (50% probability) - Continued Decline Scenario
  Revenue 2029E:        ${projections['Base Case']['revenues'][-1]/1e6:.0f}M
  FCF Margin:           {projections['Base Case']['fcf_margin']*100:.0f}%
  Terminal Growth:      {projections['Base Case']['terminal_growth']*100:.0f}%
  Enterprise Value:     ${dcf_results['Base Case']['enterprise_value']/1e6:.1f}M
  Fair Value/Share:     ${dcf_results['Base Case']['fair_value_per_share']:.2f}
  Upside vs Current:    {dcf_results['Base Case']['upside']:+.0f}%

BEAR CASE (35% probability) - Accelerated AI Disruption Scenario
  Revenue 2029E:        ${projections['Bear Case']['revenues'][-1]/1e6:.0f}M
  FCF Margin:           {projections['Bear Case']['fcf_margin']*100:.0f}%
  Terminal Growth:      {projections['Bear Case']['terminal_growth']*100:.0f}%
  Enterprise Value:     ${dcf_results['Bear Case']['enterprise_value']/1e6:.1f}M
  Fair Value/Share:     ${dcf_results['Bear Case']['fair_value_per_share']:.2f}
  Upside vs Current:    {dcf_results['Bear Case']['upside']:+.0f}%

PROBABILITY-WEIGHTED FAIR VALUE: ${weighted_fv:.2f}
  vs Current Price:     {((weighted_fv/current_price)-1)*100:+.0f}%

ALTERNATIVE VALUATIONS
----------------------
Liquidation Value:      ${liquidation_per_share:.2f}/share
  Upside vs Current:    {((liquidation_per_share/current_price)-1)*100:+.0f}%

Book Value:             ${book_value_per_share:.2f}/share
  Upside vs Current:    {((book_value_per_share/current_price)-1)*100:+.0f}%

REVERSE DCF ANALYSIS
--------------------
Current Enterprise Value: ${current_ev/1e6:.1f}M
Implied Perpetual Growth: {implied_growth*100:.1f}%
Market Expectation:       {market_expectation}

TECHNICAL ANALYSIS
------------------
Price vs 50-day SMA:    {((latest_price/latest_sma50 - 1)*100):+.1f}% (${latest_sma50:.2f})
Price vs 200-day SMA:   {((latest_price/latest_sma200 - 1)*100):+.1f}% (${latest_sma200:.2f})
RSI (14-day):           {latest_rsi:.1f} ({rsi_signal})
Trend Assessment:       {trend}
Volume Trend:           {volume_trend:+.1f}% ({volume_signal})
Key Support:            ${year_low:.2f}
Key Resistance:         ${latest_sma50:.2f}

INVESTMENT THESIS SUMMARY
-------------------------
The valuation analysis reveals significant downside risk across all scenarios:

1. SUBSCRIBER CLIFF: Revenue has collapsed from ${hist_revenues[0]:.0f}M (2021) to ${ttm_revenue/1e6:.0f}M (TTM),
   a {((ttm_revenue/1e6/hist_revenues[0])-1)*100:.0f}% decline in ~3 years, driven by AI disruption to the
   homework help/tutoring market.

2. VALUATION FLOOR: Even in the Bull Case (stabilization), fair value is only
   ${dcf_results['Bull Case']['fair_value_per_share']:.2f}/share ({dcf_results['Bull Case']['upside']:+.0f}% vs current).
   The probability-weighted value suggests {((weighted_fv/current_price)-1)*100:+.0f}% upside/downside.

3. LIQUIDATION PROTECTION: Liquidation value of ${liquidation_per_share:.2f}/share provides
   {((liquidation_per_share/current_price)-1)*100:+.0f}% vs current, offering some downside protection.

4. TECHNICAL WEAKNESS: Stock is in a {"strong downtrend" if "DOWNTREND" in trend else "weak technical position"}
   with price {"significantly" if abs((latest_price/latest_sma200 - 1)*100) > 30 else "modestly"}
   below moving averages.

5. MARKET EXPECTATIONS: The reverse DCF implies the market is pricing in {implied_growth*100:.1f}%
   perpetual growth - essentially expecting continued decline or potential business failure.

PRICE TARGETS
-------------
  Bull Case:   ${dcf_results['Bull Case']['fair_value_per_share']:.2f} ({dcf_results['Bull Case']['upside']:+.0f}%)
  Base Case:   ${dcf_results['Base Case']['fair_value_per_share']:.2f} ({dcf_results['Base Case']['upside']:+.0f}%)
  Bear Case:   ${dcf_results['Bear Case']['fair_value_per_share']:.2f} ({dcf_results['Bear Case']['upside']:+.0f}%)
  Weighted:    ${weighted_fv:.2f} ({((weighted_fv/current_price)-1)*100:+.0f}%)
  Liquidation: ${liquidation_per_share:.2f} ({((liquidation_per_share/current_price)-1)*100:+.0f}%)

================================================================================
"""

with open(RESULTS_DIR / "valuation_summary.txt", 'w') as f:
    f.write(summary_text)
print(f"  Saved: results/valuation_summary.txt")

print("\n" + "=" * 70)
print("Step 3 COMPLETE: Valuation, Subscriber Decay Modeling & Technical Analysis")
print("=" * 70)
print("\nOUTPUTS GENERATED:")
print("  - results/valuation_scenarios.csv")
print("  - results/technical_indicators.csv")
print("  - results/valuation_summary.txt")
print("  - figures/projected_revenue_scenarios.png")
print("  - figures/valuation_sensitivity.png")
print("  - figures/technical_chart.png")
print("\nKEY FINDINGS:")
print(f"  - Probability-Weighted Fair Value: ${weighted_fv:.2f} ({((weighted_fv/current_price)-1)*100:+.0f}% vs ${current_price:.2f})")
print(f"  - Bull Case Target: ${dcf_results['Bull Case']['fair_value_per_share']:.2f}")
print(f"  - Base Case Target: ${dcf_results['Base Case']['fair_value_per_share']:.2f}")
print(f"  - Bear Case Target: ${dcf_results['Bear Case']['fair_value_per_share']:.2f}")
print(f"  - Technical Setup: {trend}")
