"""
OpenSoul Hash Chain

Provides cryptographic integrity for the soul database.
Each record links to the previous one via SHA256 hash.
"""

import sqlite3
import json
import hashlib
from typing import Dict, List, Optional
from .db import get_db, DB_PATH


def compute_hash(data: Dict, prev_hash: str = "0") -> str:
    """Compute SHA256 hash for a data record."""
    content = json.dumps(data, sort_keys=True, default=str)
    return hashlib.sha256((prev_hash + content).encode()).hexdigest()


def verify_table(table: str) -> Dict:
    """Verify hash chain integrity for a table."""
    conn = get_db()
    
    cursor = conn.execute(f"SELECT * FROM {table} ORDER BY id")
    rows = cursor.fetchall()
    
    errors = []
    prev_hash = "0"
    
    for row in rows:
        row_dict = dict(row)
        stored_prev = row_dict.get("prev_hash", "0")
        stored_current = row_dict.get("current_hash", "")
        
        # Check previous hash link
        if stored_prev != prev_hash:
            errors.append({
                "id": row_dict["id"],
                "error": "prev_hash mismatch",
                "expected": prev_hash,
                "found": stored_prev
            })
        
        # Recompute current hash
        data = {k: v for k, v in row_dict.items() 
                if k not in ["id", "timestamp", "prev_hash", "current_hash"]}
        computed_hash = compute_hash(data, stored_prev)
        
        if computed_hash != stored_current:
            errors.append({
                "id": row_dict["id"],
                "error": "current_hash mismatch",
                "expected": computed_hash,
                "found": stored_current
            })
        
        prev_hash = stored_current
    
    conn.close()
    
    return {
        "table": table,
        "total_records": len(rows),
        "errors": errors,
        "valid": len(errors) == 0
    }


def verify_chain() -> Dict:
    """Verify all hash chains in the database."""
    tables = ["souls", "states", "contradictions", "silences", "artifacts", "philosophy", "profile_history"]
    
    results = {}
    all_valid = True
    
    for table in tables:
        result = verify_table(table)
        results[table] = result
        if not result["valid"]:
            all_valid = False
    
    return {
        "overall_valid": all_valid,
        "tables": results
    }


def get_chain_info(table: str) -> Dict:
    """Get chain metadata for a table."""
    conn = get_db()
    
    cursor = conn.execute(f"SELECT COUNT(*) as count FROM {table}")
    count = cursor.fetchone()["count"]
    
    cursor = conn.execute(f"SELECT current_hash FROM {table} ORDER BY id DESC LIMIT 1")
    row = cursor.fetchone()
    latest_hash = row["current_hash"] if row else None
    
    cursor = conn.execute(f"SELECT timestamp FROM {table} ORDER BY id LIMIT 1")
    row = cursor.fetchone()
    genesis_time = row["timestamp"] if row else None
    
    conn.close()
    
    return {
        "table": table,
        "record_count": count,
        "latest_hash": latest_hash,
        "genesis_time": genesis_time
    }
