"""
Relationships Tab UI

This module provides the UI for managing relationships between collections,
generating rounds, shots, and validating referential integrity.
"""

import streamlit as st
from typing import Dict, Any
from services.relationship_service import RelationshipService


def render_relationships_tab(mongo_service, config: Dict[str, Any]) -> None:
    """
    Render the Relationships management tab.
    
    Args:
        mongo_service: MongoService instance
        config: Application configuration
    """
    st.title("🔗 Relationships & Data Generation")
    
    st.markdown("""
    Manage relationships between collections and generate derived data.
    
    **Available operations:**
    - Link people to participants by code
    - Generate rounds from results
    - Generate shots from play-by-play
    - Validate referential integrity
    """)
    
    if not mongo_service.is_connected():
        st.error("❌ Not connected to MongoDB. Please check the sidebar.")
        return
    
    # Initialize relationship service
    relationship_service = RelationshipService(mongo_service)
    
    st.markdown("---")
    
    # Statistics
    _render_statistics(relationship_service)
    
    st.markdown("---")
    
    # Tabs for different operations
    tab1, tab2, tab3, tab4 = st.tabs([
        "👥 Link People",
        "🔄 Generate Rounds",
        "🎯 Generate Shots",
        "✅ Validate"
    ])
    
    with tab1:
        _render_link_people_section(relationship_service, mongo_service)
    
    with tab2:
        _render_generate_rounds_section(relationship_service, mongo_service)
    
    with tab3:
        _render_generate_shots_section(relationship_service, mongo_service)
    
    with tab4:
        _render_validation_section(relationship_service)


def _render_statistics(relationship_service: RelationshipService):
    """Render relationship statistics."""
    st.subheader("📊 Relationship Statistics")
    
    try:
        stats = relationship_service.get_relationship_statistics()
        
        col1, col2, col3, col4 = st.columns(4)
        
        with col1:
            st.metric(
                "People",
                stats.get('people', {}).get('total', 0),
                f"{stats.get('people', {}).get('with_code', 0)} with code"
            )
        
        with col2:
            participants = stats.get('participants', {})
            linked = participants.get('linked_to_people', 0)
            total = participants.get('total', 0)
            pct = f"{(linked/total*100):.1f}%" if total > 0 else "0%"
            st.metric(
                "Participants",
                total,
                f"{linked} linked ({pct})"
            )
        
        with col3:
            rounds = stats.get('rounds', {}).get('total', 0)
            st.metric("Rounds", rounds)
        
        with col4:
            shots = stats.get('shots', {}).get('total', 0)
            st.metric("Shots", shots)
    
    except Exception as e:
        st.error(f"Error loading statistics: {e}")


def _render_link_people_section(relationship_service: RelationshipService, mongo_service):
    """Render the link people to participants section."""
    st.subheader("👥 Link People to Participants")
    
    st.markdown("""
    This operation links participant records to people records by matching codes.
    
    **How it works:**
    1. Finds all people with codes
    2. Matches participants by `code` field
    3. Adds `person_id` reference to participant records
    """)
    
    # Competition filter (optional)
    competitions = mongo_service.get_distinct_values('participants', 'odf_body.competition_code')
    
    col1, col2 = st.columns([2, 1])
    
    with col1:
        competition_filter = st.selectbox(
            "Filter by Competition (optional)",
            options=['All Competitions'] + list(competitions),
            key="link_competition_filter"
        )
    
    with col2:
        st.write("")  # Spacer
        st.write("")
        if st.button("🔗 Link People to Participants", type="primary", key="link_people_btn"):
            comp_code = None if competition_filter == 'All Competitions' else competition_filter
            
            with st.spinner("Linking people to participants..."):
                result = relationship_service.link_people_to_participants(comp_code)
            
            if result['success']:
                st.success(f"""
                ✅ Linking complete!
                - **Newly linked:** {result['linked_count']}
                - **Already linked:** {result['already_linked_count']}
                - **Not found:** {result['not_found_count']}
                """)
                
                if result['not_found_codes']:
                    with st.expander(f"⚠️ Codes not found in people ({len(result['not_found_codes'])} shown)"):
                        for code in result['not_found_codes']:
                            st.text(f"  • {code}")
            else:
                st.error("❌ Linking failed")


def _render_generate_rounds_section(relationship_service: RelationshipService, mongo_service):
    """Render the generate rounds section."""
    st.subheader("🔄 Generate Rounds from Results")
    
    st.markdown("""
    This operation extracts unique rounds from results data and creates
    a separate `rounds` collection for easier querying.
    
    **Generated data:**
    - Round code and name
    - Competition and event codes
    - List of result IDs
    - Participant count
    """)
    
    # Competition selector
    competitions = mongo_service.get_distinct_values('odf_results', 'odf_body.competition_code')
    
    if not competitions:
        st.warning("⚠️ No results data found. Import results first.")
        return
    
    col1, col2 = st.columns([2, 1])
    
    with col1:
        selected_competition = st.selectbox(
            "Select Competition",
            options=competitions,
            key="rounds_competition"
        )
    
    with col2:
        st.write("")
        st.write("")
        if st.button("🔄 Generate Rounds", type="primary", key="generate_rounds_btn"):
            with st.spinner(f"Generating rounds for {selected_competition}..."):
                result = relationship_service.generate_rounds_from_results(selected_competition)
            
            if result['success']:
                st.success(f"""
                ✅ Rounds generated!
                - **New rounds:** {result['inserted_count']}
                - **Updated rounds:** {result['updated_count']}
                - **Total rounds:** {result['total_rounds']}
                """)
            else:
                st.error("❌ Generation failed")


def _render_generate_shots_section(relationship_service: RelationshipService, mongo_service):
    """Render the generate shots section."""
    st.subheader("🎯 Generate Shots from Play-by-Play")
    
    st.markdown("""
    This operation extracts individual shots from play-by-play data
    and creates a `shots` collection for detailed analysis.
    
    **Note:** This requires play-by-play data to be imported first.
    """)
    
    # Competition selector
    competitions = mongo_service.get_distinct_values('odf_play_by_play', 'odf_body.competition_code')
    
    if not competitions:
        st.warning("⚠️ No play-by-play data found. Import play-by-play first.")
        return
    
    col1, col2 = st.columns([2, 1])
    
    with col1:
        selected_competition = st.selectbox(
            "Select Competition",
            options=competitions,
            key="shots_competition"
        )
    
    with col2:
        st.write("")
        st.write("")
        if st.button("🎯 Generate Shots", type="primary", key="generate_shots_btn"):
            with st.spinner(f"Generating shots for {selected_competition}..."):
                result = relationship_service.generate_shots_from_play_by_play(selected_competition)
            
            if result['success']:
                st.success(f"""
                ✅ Shots generated!
                - **Shots created:** {result['inserted_count']}
                """)
            else:
                st.error("❌ Generation failed")


def _render_validation_section(relationship_service: RelationshipService):
    """Render the validation section."""
    st.subheader("✅ Validate Relationships")
    
    st.markdown("""
    Validate referential integrity across collections.
    Checks that all foreign key references point to existing records.
    """)
    
    collections_to_validate = ['participants', 'odf_results', 'rounds']
    
    selected_collection = st.selectbox(
        "Select Collection to Validate",
        options=collections_to_validate,
        key="validate_collection"
    )
    
    if st.button("✅ Validate", type="primary", key="validate_btn"):
        with st.spinner(f"Validating {selected_collection}..."):
            result = relationship_service.validate_relationships(selected_collection)
        
        if result['success']:
            total = result['valid_count'] + result['invalid_count']
            
            if result['invalid_count'] == 0:
                st.success(f"✅ All {result['valid_count']} records are valid!")
            else:
                st.warning(f"""
                ⚠️ Validation complete:
                - **Valid:** {result['valid_count']} / {total}
                - **Invalid:** {result['invalid_count']} / {total}
                """)
                
                if result['invalid_records']:
                    with st.expander(f"❌ Invalid records ({len(result['invalid_records'])} shown)"):
                        for rec in result['invalid_records']:
                            st.text(f"  • {rec['doc_id']}: {rec['field']} = {rec['value']} (missing in {rec['missing_in']})")
        else:
            st.info(result.get('message', 'Validation complete'))
