import os
import uuid
from pathlib import Path
import sys

PROJECT_ROOT = Path(__file__).resolve().parents[1]
if str(PROJECT_ROOT) not in sys.path:
    sys.path.insert(0, str(PROJECT_ROOT))

from neo4j import GraphDatabase
import psycopg

from app.services.storage.supabase_client import (
    check_supabase_hash,
    insert_chunks_batch,
    verify_table_exists,
)

ROOT = PROJECT_ROOT
ENV_PATH = ROOT / '.env'


def load_env_file() -> dict[str, str]:
    parsed: dict[str, str] = {}
    for raw_line in ENV_PATH.read_text().splitlines():
        line = raw_line.strip()
        if not line or line.startswith('#') or '=' not in line:
            continue
        key, value = line.split('=', 1)
        key = key.strip()
        value = value.strip()
        if len(value) >= 2 and value[0] == value[-1] and value[0] in {'"', "'"}:
            value = value[1:-1]
        elif value.endswith('"') and not value.startswith('"'):
            value = value[:-1]
        elif value.startswith('"') and not value.endswith('"'):
            value = value[1:]
        parsed[key] = value
    return parsed


def direct_db_url(env: dict[str, str]) -> str:
    return env.get('DIRECT_URL') or env['DATABASE_URL']


def main() -> None:
    env = load_env_file()
    os.environ.update(env)

    neo4j_uri = env['NEO4J_URI']
    neo4j_user = env['NEO4J_USERNAME']
    neo4j_password = env['NEO4J_PASSWORD']
    db_url = direct_db_url(env)

    test_hash = f"task4_smoke_{uuid.uuid4().hex}"
    test_title = "Task 4 Smoke Test"

    print(f"Using test hash: {test_hash}")

    print('1) Verifying document_chunks table...')
    table_ok = verify_table_exists('document_chunks')
    print(f'   table_exists={table_ok}')
    if not table_ok:
        raise RuntimeError('document_chunks table is not accessible')

    print('2) Verifying Supabase hash state before insert...')
    before_supabase = check_supabase_hash(test_hash)
    print(f'   before_supabase={before_supabase}')
    if before_supabase:
        raise RuntimeError('Test hash unexpectedly exists in Supabase before insert')

    print('3) Inserting one row into Supabase...')
    insert_result = insert_chunks_batch([
        {
            'file_hash': test_hash,
            'title': test_title,
            'chunk_index': 0,
            'metadata_header': '## Smoke Test',
            'content': 'This is a real database smoke test for Task 4.',
        }
    ])
    print(f"   insert_result={insert_result}")

    after_supabase = check_supabase_hash(test_hash)
    print(f'   after_supabase={after_supabase}')
    if not after_supabase:
        raise RuntimeError('Inserted Supabase row was not found by check_supabase_hash')

    print('4) Verifying Neo4j connectivity and writing node...')
    cypher_create = """
    MERGE (n:Literature {hash: $hash_val})
    ON CREATE SET n.title = $title
    ON MATCH SET n.title = $title
    RETURN elementId(n) AS node_id
    """
    cypher_check = "MATCH (n:Literature {hash: $hash_val}) RETURN elementId(n) AS node_id LIMIT 1"
    cypher_delete = "MATCH (n:Literature {hash: $hash_val}) DETACH DELETE n"

    with GraphDatabase.driver(neo4j_uri, auth=(neo4j_user, neo4j_password)) as driver:
        with driver.session() as session:
            result = session.run(cypher_create, hash_val=test_hash, title=test_title)
            record = result.single()
            node_id = record['node_id'] if record else None
            print(f'   created_node_id={node_id}')
            if not node_id:
                raise RuntimeError('Neo4j node was not created')

            check_result = session.run(cypher_check, hash_val=test_hash)
            check_record = check_result.single()
            node_exists = check_record is not None
            print(f'   node_exists={node_exists}')
            if not node_exists:
                raise RuntimeError('Neo4j node lookup failed after create')

    print('5) Cleaning up inserted test data...')
    with psycopg.connect(db_url, connect_timeout=10) as conn:
        with conn.cursor() as cur:
            cur.execute('DELETE FROM document_chunks WHERE file_hash = %s', (test_hash,))
            deleted_rows = cur.rowcount
        conn.commit()
    print(f'   deleted_supabase_rows={deleted_rows}')

    with GraphDatabase.driver(neo4j_uri, auth=(neo4j_user, neo4j_password)) as driver:
        with driver.session() as session:
            session.run(cypher_delete, hash_val=test_hash)

    final_supabase = check_supabase_hash(test_hash)
    print(f'   final_supabase={final_supabase}')
    if final_supabase:
        raise RuntimeError('Supabase row still exists after cleanup')

    print('6) Real database smoke test finished successfully.')


if __name__ == '__main__':
    main()
