import sys
from neo4j import GraphDatabase
from dotenv import load_dotenv
import os
import requests
import json
from flatten_json import flatten

# Global variable to store the list of bill numbers
bill_numbers = []

def search_bills(bill_type):
    # Load environment variables from .env file
    load_dotenv()

    # Get connection information from environment variables
    uri = os.getenv('NEO4J_URI')
    user = os.getenv('NEO4J_USER')
    password = os.getenv('NEO4J_PASSWORD')

    # Connect to Neo4j database
    driver = GraphDatabase.driver(uri, auth=(user, password))

    try:
        with driver.session() as session:
            # Query to find nodes with label 'Bill' and property 'type' matching the provided value
            query = "MATCH (b:Law) WHERE b.laws_0_type = 'Public Law' RETURN b.number"

            # Execute the query
            result = session.run(query, bill_type=bill_type)

            # Collect the list of bill numbers
            global bill_numbers
            bill_numbers = [record["b.number"] for record in result]
    finally:
        # Close the driver connection
        driver.close()

def get_bill_details(congress, bill_type, bill_number):
    url = f"https://api.congress.gov/v3/law/{congress}/{bill_type.lower()}/{bill_number}?format=json&api_key={os.getenv('CONGRESS_API_KEY')}"
    response = requests.get(url)
    if response.status_code == 200:
        return response.json()
    else:
        print(f"Failed to fetch bill details for {bill_number}: {response.status_code}")
        print(f"Response Text: {response.text}")
        return None

def flatten_json(y):
    out = {}

    def flatten(x, name=''):
        if type(x) is dict:
            for a in x:
                flatten(x[a], name + a + '.')
        elif type(x) is list:
            i = 0
            for a in x:
                flatten(a, name + str(i) + '.')
                i += 1
        else:
            out[name[:-1]] = x

    flatten(y)
    return {k.replace('bill.', ''): v for k, v in out.items()}

def update_bill_node(driver, bill_number, properties):
    with driver.session() as session:
        # Remove existing properties
        query_remove_properties = f"MATCH (b:Law {{number: $bill_number}}) SET b += {{}}"
        session.run(query_remove_properties, bill_number=bill_number)

        # Add new properties
        query_add_properties = f"MATCH (b:Law {{number: $bill_number}}) SET b += $properties RETURN b"
        session.run(query_add_properties, bill_number=bill_number, properties=properties)

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("Usage: python search_bills.py <congress> <bill_type>")
        sys.exit(1)

    congress = sys.argv[1]
    bill_type = sys.argv[2]

    search_bills(bill_type)

    # Connect to Neo4j database
    driver = GraphDatabase.driver(os.getenv('NEO4J_URI'), auth=(os.getenv('NEO4J_USER'), os.getenv('NEO4J_PASSWORD')))

    for bill_number in bill_numbers:
        print(f"Fetching details for bill number {bill_number}...")
        bill_details = get_bill_details(congress, bill_type, bill_number)
        if bill_details:
            flattened_properties = flatten_json(bill_details)
            update_bill_node(driver, bill_number, flattened_properties)
            print(f"Updated bill node with properties from JSON response for bill number {bill_number}")

    # Close the driver connection
    driver.close()
