#!/usr/bin/env python3
"""
Seed data script for ResolutionFlow decision trees.

This script creates example troubleshooting trees in the database.
Run from the backend directory with: python -m scripts.seed_data

Requirements:
- Backend server must be running (uvicorn app.main:app)
- Or run with --direct flag to insert directly to database
"""

import asyncio
import argparse
import httpx
from typing import Any


# API Configuration
API_BASE_URL = "http://localhost:8000/api/v1"

# Default admin user for seeding (will be created if doesn't exist)
SEED_USER = {
    "email": "seed.admin@example.com",
    "password": "SeedAdmin123!",
    "name": "Seed Admin",
    "role": "admin"
}


# =============================================================================
# TREE DEFINITIONS
# =============================================================================

def get_password_reset_tree() -> dict[str, Any]:
    """
    Password Reset Request - Simple troubleshooting tree.
    Based on TS-EXAMPLES.md Scenario 5.
    """
    return {
        "name": "Password Reset Request",
        "description": "Guide for handling user password reset requests safely and efficiently. Covers identity verification, account status checks, and common issues.",
        "category": "Account Management",
        "tree_structure": {
            "id": "root",
            "type": "decision",
            "question": "Can you verify the user's identity?",
            "help_text": "Check against company verification policy (phone callback, email verification, or manager confirmation)",
            "options": [
                {"id": "verified", "label": "Yes, identity verified", "next_node_id": "find_account"},
                {"id": "not_verified", "label": "No, cannot verify", "next_node_id": "deny_request"},
                {"id": "contractor", "label": "User is a contractor", "next_node_id": "contractor_approval"}
            ],
            "children": [
                {
                    "id": "deny_request",
                    "type": "solution",
                    "title": "Deny Request - Cannot Verify Identity",
                    "description": "Inform the user that you cannot process their request without proper identity verification.\n\n**Actions:**\n- Politely explain the verification requirements\n- Provide alternative verification methods they can use\n- Document the denied request in the ticket system\n\n**Do NOT reset the password under any circumstances.**"
                },
                {
                    "id": "contractor_approval",
                    "type": "decision",
                    "question": "Does the contractor's manager approve the reset?",
                    "help_text": "Per company policy, contractor password resets require manager approval",
                    "options": [
                        {"id": "manager_approves", "label": "Manager approves", "next_node_id": "find_account"},
                        {"id": "manager_denies", "label": "Manager denies", "next_node_id": "contractor_denied"},
                        {"id": "manager_unavailable", "label": "Cannot reach manager", "next_node_id": "escalate_manager"}
                    ],
                    "children": [
                        {
                            "id": "contractor_denied",
                            "type": "solution",
                            "title": "Request Denied by Manager",
                            "description": "Inform the contractor that their manager has denied the password reset request.\n\n**Actions:**\n- Document the denial in the ticket\n- Advise contractor to follow up with their manager directly\n- Close the ticket as 'Denied'"
                        },
                        {
                            "id": "escalate_manager",
                            "type": "solution",
                            "title": "Escalate to IT Manager",
                            "description": "Cannot reach contractor's manager for approval.\n\n**Actions:**\n- Escalate ticket to IT Manager for decision\n- Document attempts to reach the contractor's manager\n- Set ticket status to 'Pending Approval'\n\n**Do NOT reset the password until approval is received.**"
                        }
                    ]
                },
                {
                    "id": "find_account",
                    "type": "decision",
                    "question": "Can you find the user's account in Active Directory?",
                    "help_text": "Search AD by username, email, or employee name",
                    "options": [
                        {"id": "account_found", "label": "Account found", "next_node_id": "check_account_status"},
                        {"id": "account_not_found", "label": "Account not found", "next_node_id": "check_spelling"},
                        {"id": "multiple_accounts", "label": "Multiple accounts found", "next_node_id": "identify_account"}
                    ],
                    "children": [
                        {
                            "id": "check_spelling",
                            "type": "decision",
                            "question": "Is the username spelled correctly?",
                            "help_text": "Verify spelling with the user, check for common variations",
                            "options": [
                                {"id": "found_correct", "label": "Found with correct spelling", "next_node_id": "check_account_status"},
                                {"id": "still_not_found", "label": "Still not found", "next_node_id": "no_account_exists"},
                                {"id": "user_no_account", "label": "User doesn't have an account", "next_node_id": "no_account_exists"}
                            ],
                            "children": [
                                {
                                    "id": "no_account_exists",
                                    "type": "solution",
                                    "title": "Account Does Not Exist",
                                    "description": "The user does not have an Active Directory account.\n\n**Actions:**\n- Verify with HR if user should have an account\n- If new employee: Route to New User Request process\n- If existing employee: Escalate to AD team for investigation\n- Document findings in the ticket"
                                }
                            ]
                        },
                        {
                            "id": "identify_account",
                            "type": "decision",
                            "question": "Can you identify the correct account?",
                            "help_text": "Use employee ID, department, manager name, or start date to identify",
                            "options": [
                                {"id": "identified_by_id", "label": "Identified by employee ID", "next_node_id": "check_account_status"},
                                {"id": "identified_by_dept", "label": "Identified by department", "next_node_id": "check_account_status"},
                                {"id": "cannot_identify", "label": "Cannot identify correct account", "next_node_id": "need_more_info"}
                            ],
                            "children": [
                                {
                                    "id": "need_more_info",
                                    "type": "solution",
                                    "title": "Request Additional Information",
                                    "description": "Cannot determine which account belongs to the user.\n\n**Actions:**\n- Ask user for:\n  - Employee ID\n  - Department\n  - Manager's name\n  - Hire/start date\n  - Last known working username\n- Once identified, continue with account status check"
                                }
                            ]
                        },
                        {
                            "id": "check_account_status",
                            "type": "decision",
                            "question": "What is the account status?",
                            "help_text": "Check if account is enabled, disabled, or locked in AD",
                            "options": [
                                {"id": "enabled", "label": "Account is enabled", "next_node_id": "reset_password"},
                                {"id": "disabled", "label": "Account is disabled", "next_node_id": "check_disabled_reason"},
                                {"id": "locked", "label": "Account is locked out", "next_node_id": "unlock_account"}
                            ],
                            "children": [
                                {
                                    "id": "check_disabled_reason",
                                    "type": "decision",
                                    "question": "Why is the account disabled?",
                                    "help_text": "Check account notes, ticket history, or HR records",
                                    "options": [
                                        {"id": "terminated", "label": "Disabled for termination", "next_node_id": "terminated_user"},
                                        {"id": "inactive", "label": "Disabled for inactivity", "next_node_id": "verify_employment"},
                                        {"id": "disabled_error", "label": "Disabled in error", "next_node_id": "enable_and_reset"}
                                    ],
                                    "children": [
                                        {
                                            "id": "terminated_user",
                                            "type": "solution",
                                            "title": "Account Disabled - User Terminated",
                                            "description": "**DO NOT ENABLE THIS ACCOUNT**\n\nThe account was disabled because the user has been terminated.\n\n**Actions:**\n- Inform the requester that the account cannot be enabled\n- If this is an error, direct them to HR to verify employment status\n- Document the request and denial in the ticket\n- Close ticket as 'Denied - Terminated User'"
                                        },
                                        {
                                            "id": "verify_employment",
                                            "type": "decision",
                                            "question": "Is the user still employed?",
                                            "help_text": "Verify with HR or the user's manager",
                                            "options": [
                                                {"id": "still_employed", "label": "Still employed", "next_node_id": "enable_and_reset"},
                                                {"id": "terminated_confirmed", "label": "Terminated", "next_node_id": "terminated_user"},
                                                {"id": "unknown_status", "label": "Unknown status", "next_node_id": "escalate_employment"}
                                            ],
                                            "children": [
                                                {
                                                    "id": "escalate_employment",
                                                    "type": "solution",
                                                    "title": "Escalate to IT Manager",
                                                    "description": "Cannot verify employment status.\n\n**Actions:**\n- Escalate ticket to IT Manager\n- Document all verification attempts\n- Do NOT enable the account until status is confirmed"
                                                },
                                                {
                                                    "id": "enable_and_reset",
                                                    "type": "action",
                                                    "title": "Enable Account and Reset Password",
                                                    "description": "Account should be re-enabled.\n\n**Actions:**\n1. Enable the account in Active Directory\n2. Continue to password reset step",
                                                    "next_node_id": "reset_password"
                                                }
                                            ]
                                        }
                                    ]
                                },
                                {
                                    "id": "unlock_account",
                                    "type": "action",
                                    "title": "Unlock Account",
                                    "description": "Account is locked out, likely from too many failed login attempts.\n\n**Actions:**\n1. Unlock the account in Active Directory\n2. Continue to reset password",
                                    "action_command": "Unlock-ADAccount -Identity USERNAME",
                                    "next_node_id": "reset_password"
                                },
                                {
                                    "id": "reset_password",
                                    "type": "decision",
                                    "question": "Were you able to reset the password?",
                                    "help_text": "Set a temporary password in AD with 'User must change password at next logon' checked",
                                    "action_command": "Set-ADAccountPassword -Identity USERNAME -Reset -NewPassword (ConvertTo-SecureString 'TempPass123!' -AsPlainText -Force)",
                                    "options": [
                                        {"id": "reset_success", "label": "Reset successful", "next_node_id": "communicate_password"},
                                        {"id": "reset_denied", "label": "Permission denied", "next_node_id": "escalate_reset"},
                                        {"id": "reset_but_fails", "label": "Reset but user still can't login", "next_node_id": "check_login_issue"}
                                    ],
                                    "children": [
                                        {
                                            "id": "escalate_reset",
                                            "type": "solution",
                                            "title": "Escalate to Higher-Level Admin",
                                            "description": "You don't have permission to reset this user's password.\n\n**This typically happens for:**\n- Executive accounts\n- Service accounts\n- Accounts in protected OUs\n\n**Actions:**\n- Escalate to Tier 2 or AD Administrator\n- Document the account and reason for escalation"
                                        },
                                        {
                                            "id": "check_login_issue",
                                            "type": "decision",
                                            "question": "What is preventing login?",
                                            "help_text": "Common issues after password reset",
                                            "options": [
                                                {"id": "wrong_username", "label": "User entering wrong username", "next_node_id": "provide_username"},
                                                {"id": "caps_lock", "label": "Caps Lock is on", "next_node_id": "caps_lock_fix"},
                                                {"id": "not_synced", "label": "Password not synced yet", "next_node_id": "wait_sync"},
                                                {"id": "mfa_issue", "label": "MFA/2FA issue", "next_node_id": "mfa_separate"}
                                            ],
                                            "children": [
                                                {
                                                    "id": "provide_username",
                                                    "type": "solution",
                                                    "title": "Provide Correct Username",
                                                    "description": "User is entering the wrong username.\n\n**Actions:**\n- Provide the correct username format (e.g., jsmith or john.smith@company.com)\n- Have user try again with correct credentials\n- Verify successful login"
                                                },
                                                {
                                                    "id": "caps_lock_fix",
                                                    "type": "solution",
                                                    "title": "Caps Lock Issue",
                                                    "description": "User has Caps Lock enabled.\n\n**Actions:**\n- Inform user to turn off Caps Lock\n- Have user retry login\n- Verify successful login"
                                                },
                                                {
                                                    "id": "wait_sync",
                                                    "type": "solution",
                                                    "title": "Wait for Password Sync",
                                                    "description": "Password may not have synchronized to all systems yet.\n\n**Actions:**\n- Wait 2-5 minutes for AD replication\n- If using Azure AD Connect, sync may take up to 30 minutes\n- Have user retry after waiting\n- If still failing after 30 minutes, check replication status"
                                                },
                                                {
                                                    "id": "mfa_separate",
                                                    "type": "solution",
                                                    "title": "MFA Issue - Separate Troubleshooting",
                                                    "description": "User has a Multi-Factor Authentication issue.\n\n**This is a separate troubleshooting path.**\n\n**Common MFA issues:**\n- Authenticator app not set up\n- Phone number changed\n- Hardware token lost\n\n**Actions:**\n- Create a new ticket for MFA troubleshooting\n- Or escalate to Identity Management team"
                                                }
                                            ]
                                        },
                                        {
                                            "id": "communicate_password",
                                            "type": "decision",
                                            "question": "How was the password communicated to the user?",
                                            "help_text": "Ensure secure delivery of temporary password",
                                            "options": [
                                                {"id": "told_phone", "label": "Told over phone", "next_node_id": "verify_login"},
                                                {"id": "secure_portal", "label": "Sent via secure portal", "next_node_id": "verify_login"},
                                                {"id": "user_received", "label": "User confirmed receipt", "next_node_id": "verify_login"}
                                            ],
                                            "children": [
                                                {
                                                    "id": "verify_login",
                                                    "type": "decision",
                                                    "question": "Was the user able to log in successfully?",
                                                    "help_text": "Confirm with user that they can access their account",
                                                    "options": [
                                                        {"id": "login_success", "label": "Login successful", "next_node_id": "resolution_success"},
                                                        {"id": "login_failed", "label": "Still cannot log in", "next_node_id": "check_login_issue"}
                                                    ],
                                                    "children": [
                                                        {
                                                            "id": "resolution_success",
                                                            "type": "solution",
                                                            "title": "[OK] Password Reset Complete",
                                                            "description": "User has successfully logged in with their new password.\n\n**Final Steps:**\n1. Confirm user was prompted to change their password\n2. Verify user successfully set a new personal password\n3. Document the resolution in the ticket\n4. Close the ticket as 'Resolved'\n\n**Resolution Indicators:**\n- User confirms successful login\n- Account shows updated 'Last Logon' timestamp\n- No subsequent lockouts or reset requests"
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    }


def get_file_share_access_tree() -> dict[str, Any]:
    """
    User Cannot Access File Share - Medium complexity troubleshooting tree.
    Based on TS-EXAMPLES.md Scenario 3.
    (Stub for future implementation)
    """
    return {
        "name": "File Share Access Issues",
        "description": "Troubleshoot user access to network file shares. Covers network connectivity, permissions, and SMB issues.",
        "category": "File Services",
        "tree_structure": {
            "id": "root",
            "type": "decision",
            "question": "Can the user ping the file server by name?",
            "options": [
                {"id": "ping_success", "label": "Yes, ping succeeds", "next_node_id": "check_share_access"},
                {"id": "ping_timeout", "label": "No, request timed out", "next_node_id": "network_issue"},
                {"id": "unknown_host", "label": "Unknown host error", "next_node_id": "dns_issue"}
            ],
            "children": [
                {
                    "id": "check_share_access",
                    "type": "solution",
                    "title": "Check Share Access (Placeholder)",
                    "description": "This tree will be expanded in a future update.\n\nFor now, check:\n1. Share permissions\n2. NTFS permissions\n3. User group memberships"
                },
                {
                    "id": "network_issue",
                    "type": "solution",
                    "title": "Network Connectivity Issue (Placeholder)",
                    "description": "This tree will be expanded in a future update.\n\nCheck:\n1. VPN status if remote\n2. Network cable/WiFi connection\n3. Firewall rules"
                },
                {
                    "id": "dns_issue",
                    "type": "solution",
                    "title": "DNS Resolution Issue (Placeholder)",
                    "description": "This tree will be expanded in a future update.\n\nRun: nslookup FILE-SERVER-NAME\n\nCheck DNS configuration on user's PC."
                }
            ]
        }
    }


# =============================================================================
# SEEDING FUNCTIONS
# =============================================================================

async def get_or_create_admin_user(client: httpx.AsyncClient) -> tuple[str, dict]:
    """Get authentication token for seeding. Creates admin user if needed."""

    # Try to login first
    login_response = await client.post(
        f"{API_BASE_URL}/auth/login/json",
        json={"email": SEED_USER["email"], "password": SEED_USER["password"]}
    )

    if login_response.status_code == 200:
        token_data = login_response.json()
        return token_data["access_token"], {"exists": True}

    # User doesn't exist, create them
    register_response = await client.post(
        f"{API_BASE_URL}/auth/register",
        json=SEED_USER
    )

    if register_response.status_code not in (200, 201):
        raise Exception(f"Failed to create seed user: {register_response.text}")

    # Now login
    login_response = await client.post(
        f"{API_BASE_URL}/auth/login/json",
        json={"email": SEED_USER["email"], "password": SEED_USER["password"]}
    )

    if login_response.status_code != 200:
        raise Exception(f"Failed to login as seed user: {login_response.text}")

    token_data = login_response.json()
    return token_data["access_token"], {"exists": False, "user": register_response.json()}


async def create_tree(client: httpx.AsyncClient, token: str, tree_data: dict) -> dict:
    """Create a tree via the API."""
    headers = {"Authorization": f"Bearer {token}"}

    # Check if tree with same name exists
    list_response = await client.get(f"{API_BASE_URL}/trees", headers=headers)
    if list_response.status_code == 200:
        existing_trees = list_response.json()
        for tree in existing_trees:
            if tree["name"] == tree_data["name"]:
                print(f"  [SKIP]  Tree '{tree_data['name']}' already exists (ID: {tree['id']})")
                return tree

    # Create the tree
    response = await client.post(
        f"{API_BASE_URL}/trees",
        json=tree_data,
        headers=headers
    )

    if response.status_code not in (200, 201):
        raise Exception(f"Failed to create tree '{tree_data['name']}': {response.text}")

    tree = response.json()
    print(f"  [OK] Created tree '{tree_data['name']}' (ID: {tree['id']})")
    return tree


async def seed_database():
    """Main seeding function."""
    print("\n[*] ResolutionFlow Database Seeder")
    print("=" * 50)

    async with httpx.AsyncClient(timeout=30.0) as client:
        # Check if API is running
        try:
            health_check = await client.get(f"{API_BASE_URL.replace('/api/v1', '')}/health")
        except httpx.ConnectError:
            print("\n[ERROR] Error: Cannot connect to API server")
            print(f"   Make sure the server is running at {API_BASE_URL}")
            print("   Run: uvicorn app.main:app --reload")
            return False

        # Get or create admin user
        print("\n[1/2] Setting up seed user...")
        try:
            token, user_info = await get_or_create_admin_user(client)
            if user_info.get("exists"):
                print("  [OK] Using existing seed admin user")
            else:
                print(f"  [OK] Created seed admin user: {SEED_USER['email']}")
        except Exception as e:
            print(f"  [ERROR] Failed to setup seed user: {e}")
            return False

        # Create trees
        print("\n[2/2] Creating decision trees...")

        trees_to_create = [
            get_password_reset_tree(),
            get_file_share_access_tree(),
        ]

        created_trees = []
        for tree_data in trees_to_create:
            try:
                tree = await create_tree(client, token, tree_data)
                created_trees.append(tree)
            except Exception as e:
                print(f"  [ERROR] Failed to create '{tree_data['name']}': {e}")

        # Summary
        print("\n" + "=" * 50)
        print(f"[OK] Seeding complete! Created {len(created_trees)} trees.")
        print("\nCreated trees:")
        for tree in created_trees:
            print(f"  - {tree['name']} ({tree['category']})")

        return True


def main():
    parser = argparse.ArgumentParser(description="Seed the ResolutionFlow database with example trees")
    parser.add_argument("--direct", action="store_true", help="Insert directly to database (not implemented)")
    args = parser.parse_args()

    if args.direct:
        print("Direct database insertion not yet implemented. Using API method.")

    success = asyncio.run(seed_database())
    exit(0 if success else 1)


if __name__ == "__main__":
    main()
