#!/usr/bin/env python3
"""
Master User Creation Script for Positeasy Canteen Automation System.

This script creates or updates a master administrator user in the database
with username 'admin' and password 'admin', and synchronizes the application configuration.
"""

import sys
import os
import re
import argparse
import bcrypt
import psycopg2

# Default Configuration
DEFAULT_USERNAME = "admin"
DEFAULT_PASSWORD = "admin"
DEFAULT_NAME = "Admin Master"
DEFAULT_ROLE = "MASTER"

DEFAULT_DB_HOST = "localhost"
DEFAULT_DB_PORT = 5432
DEFAULT_DB_NAME = "positeasy"
DEFAULT_DB_USER = "postgres"
DEFAULT_DB_PASS = "sidharth"

ALL_PERMISSIONS = [
    "dashboard",
    "sale",
    "customers",
    "purchases",
    "inventory",
    "expense",
    "reports",
    "stores",
    "table",
    "wallet",
    "promotions",
    "feedback"
]

def hash_password(password: str) -> str:
    """Hash password using bcrypt compatible with Spring Security BCryptPasswordEncoder."""
    salt = bcrypt.gensalt(rounds=10)
    hashed = bcrypt.hashpw(password.encode('utf-8'), salt)
    return hashed.decode('utf-8')

def parse_application_properties(prop_path: str) -> dict:
    """Parse db credentials from backend application.properties if available."""
    config = {}
    if not os.path.exists(prop_path):
        return config

    with open(prop_path, 'r', encoding='utf-8') as f:
        for line in f:
            line = line.strip()
            if line and not line.startswith('#') and '=' in line:
                key, value = line.split('=', 1)
                config[key.strip()] = value.strip()
    return config

def update_application_properties(prop_path: str, username: str, password: str) -> bool:
    """Update app.master.username and app.master.password in application.properties."""
    if not os.path.exists(prop_path):
        print(f"⚠️  [Config] File not found: {prop_path}")
        return False

    with open(prop_path, 'r', encoding='utf-8') as f:
        content = f.read()

    # Update or add app.master.username and app.master.password
    new_user_line = f"app.master.username=${{MASTER_USER:{username}}}"
    new_pass_line = f"app.master.password=${{MASTER_PASSWORD:{password}}}"

    if re.search(r'^app\.master\.username=.*$', content, flags=re.MULTILINE):
        content = re.sub(r'^app\.master\.username=.*$', new_user_line, content, flags=re.MULTILINE)
    else:
        content += f"\n{new_user_line}"

    if re.search(r'^app\.master\.password=.*$', content, flags=re.MULTILINE):
        content = re.sub(r'^app\.master\.password=.*$', new_pass_line, content, flags=re.MULTILINE)
    else:
        content += f"\n{new_pass_line}"

    with open(prop_path, 'w', encoding='utf-8') as f:
        f.write(content)

    print(f"✅ [Config] Updated {prop_path} with default master credentials ({username}/{password}).")
    return True

def update_frontend_demo_credentials(app_tsx_path: str, username: str, password: str) -> bool:
    """Update UI demo credentials displayed in api-dashboard if file exists."""
    if not os.path.exists(app_tsx_path):
        return False

    with open(app_tsx_path, 'r', encoding='utf-8') as f:
        content = f.read()

    old_pattern = r'Default Admin:\s*<strong>[^<]*</strong>\s*/\s*Password:\s*<strong>[^<]*</strong>'
    new_text = f'Default Admin: <strong>{username}</strong> / Password: <strong>{password}</strong>'

    if re.search(old_pattern, content):
        content = re.sub(old_pattern, new_text, content)
        with open(app_tsx_path, 'w', encoding='utf-8') as f:
            f.write(content)
        print(f"✅ [UI] Updated demo credentials in {app_tsx_path}.")
        return True
    return False

def create_or_update_master_user(db_params: dict, username: str, password: str, name: str) -> bool:
    """Insert or update master user in PostgreSQL database."""
    print(f"\n🔌 Connecting to PostgreSQL database '{db_params['dbname']}' on {db_params['host']}:{db_params['port']}...")

    try:
        conn = psycopg2.connect(**db_params)
        conn.autocommit = False
        cur = conn.cursor()

        # Check if system_users table exists
        cur.execute("""
            SELECT EXISTS (
                SELECT FROM information_schema.tables 
                WHERE table_name = 'system_users'
            );
        """)
        table_exists = cur.fetchone()[0]

        if not table_exists:
            print("❌ Table 'system_users' does not exist in the database. Has backend schema initialized?")
            conn.close()
            return False

        # Check if master user with this username (stored in email column) exists
        cur.execute("SELECT id, name, role FROM system_users WHERE email = %s;", (username,))
        row = cur.fetchone()

        hashed_pass = hash_password(password)

        if row:
            user_id = row[0]
            print(f"🔄 Existing master user found (ID: {user_id}). Updating credentials...")
            cur.execute("""
                UPDATE system_users 
                SET name = %s, password = %s, role = %s, view_only = false 
                WHERE id = %s;
            """, (name, hashed_pass, DEFAULT_ROLE, user_id))
        else:
            print(f"➕ Creating new master user '{username}'...")
            cur.execute("""
                INSERT INTO system_users (name, email, password, role, view_only)
                VALUES (%s, %s, %s, %s, false)
                RETURNING id;
            """, (name, username, hashed_pass, DEFAULT_ROLE))
            user_id = cur.fetchone()[0]

        # Reset permissions for this user
        cur.execute("DELETE FROM system_user_permissions WHERE user_id = %s;", (user_id,))
        for perm in ALL_PERMISSIONS:
            cur.execute("""
                INSERT INTO system_user_permissions (user_id, permission)
                VALUES (%s, %s);
            """, (user_id, perm))

        conn.commit()

        # Verification query
        cur.execute("""
            SELECT u.id, u.name, u.email, u.role, count(p.permission)
            FROM system_users u
            LEFT JOIN system_user_permissions p ON u.id = p.user_id
            WHERE u.id = %s
            GROUP BY u.id, u.name, u.email, u.role;
        """, (user_id,))
        ver = cur.fetchone()
        cur.close()
        conn.close()

        print("\n" + "=" * 50)
        print("🎉 MASTER USER CREATED / UPDATED SUCCESSFULLY")
        print("=" * 50)
        print(f"  User ID:     {ver[0]}")
        print(f"  Name:        {ver[1]}")
        print(f"  Username:    {ver[2]}")
        print(f"  Password:    {password}")
        print(f"  Role:        {ver[3]}")
        print(f"  Permissions: {ver[4]} granted ({', '.join(ALL_PERMISSIONS[:4])}...)")
        print("=" * 50 + "\n")
        return True

    except Exception as e:
        print(f"❌ Database error: {e}")
        return False

def main():
    parser = argparse.ArgumentParser(description="Create or update master user for Positeasy Canteen Automation.")
    parser.add_argument("-u", "--username", default=DEFAULT_USERNAME, help="Master username (default: admin)")
    parser.add_argument("-p", "--password", default=DEFAULT_PASSWORD, help="Master password (default: admin)")
    parser.add_argument("-n", "--name", default=DEFAULT_NAME, help="Display name for master user")
    parser.add_argument("--host", default=DEFAULT_DB_HOST, help="PostgreSQL host (default: localhost)")
    parser.add_argument("--port", type=int, default=DEFAULT_DB_PORT, help="PostgreSQL port (default: 5432)")
    parser.add_argument("--dbname", default=DEFAULT_DB_NAME, help="PostgreSQL database name (default: positeasy)")
    parser.add_argument("--dbuser", default=DEFAULT_DB_USER, help="PostgreSQL database user (default: postgres)")
    parser.add_argument("--dbpass", default=DEFAULT_DB_PASS, help="PostgreSQL database password")
    
    args = parser.parse_args()

    project_root = os.path.dirname(os.path.abspath(__file__))
    prop_path = os.path.join(project_root, "backend", "src", "main", "resources", "application.properties")
    app_tsx_path = os.path.join(project_root, "api-dashboard", "src", "App.tsx")

    db_params = {
        "host": args.host,
        "port": args.port,
        "dbname": args.dbname,
        "user": args.dbuser,
        "password": args.dbpass
    }

    print("🚀 Starting Master User setup script...")

    # 1. Database creation / update
    db_success = create_or_update_master_user(db_params, args.username, args.password, args.name)

    # 2. Sync application.properties
    update_application_properties(prop_path, args.username, args.password)

    # 3. Sync frontend dashboard UI
    update_frontend_demo_credentials(app_tsx_path, args.username, args.password)

    if db_success:
        print("✨ All steps completed successfully! You can now log in with:")
        print(f"   Username: {args.username}")
        print(f"   Password: {args.password}")
    else:
        print("⚠️ Database operation failed or incomplete. Check database connectivity.")

if __name__ == "__main__":
    main()
