import sqlite3
import json
import sys
import os

# Configuration
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DB_PATH = os.path.join(BASE_DIR, "database", "pvz.db")

ALL_PLANTS = [
    "peashooter", "acid_lemon", "sunflower", "pod_peashooter", "bomber", "torchwood", "watermelon",
    "iced_coconut", "trumpet", "pine_shooter", "gold_bloom", "spiky_pumpkin",
    "jalapeno_pair", "mimic", "reshaper", "time_machine", "laser_shroom", "windmill",
    "vine_trap", "electrode_cherry", "wild_gatling", "ninja_nut", "citron",
    "corn_homing", "corn_gatling", "jelly", "binary_tree", "maguey", "christmas_nut", "grape_pult",
    "sword_gourd", "coffee_bean", "bowling_nut"
]

ALL_ZOMBIES = [
    "normal", "buckethead", "exploder", "fisher", "football", "football_forward",
    "gargantuar", "priest", "siren"
]

DEFAULT_PLANTS = ["peashooter", "sunflower", "pod_peashooter", "watermelon", "pine_shooter"]
DEFAULT_ZOMBIES = ["normal", "buckethead", "exploder"]

def get_db_connection():
    return sqlite3.connect(DB_PATH)

def query_all():
    conn = get_db_connection()
    c = conn.cursor()
    c.execute("SELECT username, inventory, plant_slots, zombie_slots FROM users")
    users = c.fetchall()
    conn.close()
    
    print(f"{'Username':<20} | {'Plants':<10} | {'Zombies':<10} | {'P-Slots':<8} | {'Z-Slots':<8}")
    print("-" * 75)
    for row in users:
        username = row[0]
        inv_json = row[1]
        plant_slots = row[2] if len(row) > 2 and row[2] is not None else 10
        zombie_slots = row[3] if len(row) > 3 and row[3] is not None else 10
        
        try:
            inv = json.loads(inv_json)
            p_count = len(inv.get('plants', []))
            z_count = len(inv.get('zombies', []))
            print(f"{username:<20} | {p_count:<10} | {z_count:<10} | {plant_slots:<8} | {zombie_slots:<8}")
        except:
            print(f"{username:<20} | Error parsing inventory")

def query_user(username):
    conn = get_db_connection()
    c = conn.cursor()
    c.execute("SELECT inventory, deck, plant_levels, plant_slots, zombie_slots FROM users WHERE username = ?", (username,))
    row = c.fetchone()
    conn.close()
    
    if not row:
        print(f"User '{username}' not found.")
        return

    try:
        inv = json.loads(row[0])
        deck = json.loads(row[1]) if len(row) > 1 and row[1] else {'plants': [], 'zombies': []}
        plant_levels = json.loads(row[2]) if len(row) > 2 and row[2] else {}
        plant_slots = row[3] if len(row) > 3 and row[3] is not None else 10
        zombie_slots = row[4] if len(row) > 4 and row[4] is not None else 10
        
        print(f"\n{'='*60}")
        print(f"User: {username}")
        print(f"{'='*60}")
        
        print(f"\n[Inventory]")
        print(f"  Plants ({len(inv.get('plants', []))} cards): {', '.join(inv.get('plants', [])) or 'None'}")
        print(f"  Zombies ({len(inv.get('zombies', []))} cards): {', '.join(inv.get('zombies', [])) or 'None'}")
        
        print(f"\n[Deck Slots]")
        print(f"  Plant Slots: {plant_slots}")
        print(f"  Zombie Slots: {zombie_slots}")
        
        print(f"\n[Current Deck]")
        deck_plants = deck.get('plants', [])
        deck_zombies = deck.get('zombies', [])
        print(f"  Plants ({len(deck_plants)}/{plant_slots}): {', '.join(deck_plants) or 'None'}")
        print(f"  Zombies ({len(deck_zombies)}/{zombie_slots}): {', '.join(deck_zombies) or 'None'}")
        
        if plant_levels:
            print(f"\n[Plant Levels]")
            for plant, level in sorted(plant_levels.items()):
                if level > 0:
                    print(f"  {plant}: Lv.{level}")
        
        print(f"{'='*60}\n")
    except Exception as e:
        print(f"Error parsing data for {username}: {e}")

def add_card(username, card_name):
    conn = get_db_connection()
    c = conn.cursor()
    c.execute("SELECT inventory FROM users WHERE username = ?", (username,))
    row = c.fetchone()
    
    if not row:
        print(f"User '{username}' not found.")
        conn.close()
        return

    try:
        inv = json.loads(row[0])
        plants = inv.get('plants', [])
        zombies = inv.get('zombies', [])
        
        updated = False
        
        if card_name == 'all':
            inv['plants'] = list(set(plants + ALL_PLANTS))
            inv['zombies'] = list(set(zombies + ALL_ZOMBIES))
            updated = True
            print(f"Unlocked ALL cards for {username}.")
        else:
            if card_name in ALL_PLANTS:
                if card_name not in plants:
                    plants.append(card_name)
                    updated = True
                    print(f"Unlocked plant '{card_name}' for {username}.")
                else:
                    print(f"User already has plant '{card_name}'.")
            elif card_name in ALL_ZOMBIES:
                if card_name not in zombies:
                    zombies.append(card_name)
                    updated = True
                    print(f"Unlocked zombie '{card_name}' for {username}.")
                else:
                    print(f"User already has zombie '{card_name}'.")
            else:
                print(f"Card '{card_name}' not found in database.")
        
        if updated:
            c.execute("UPDATE users SET inventory = ? WHERE username = ?", (json.dumps(inv), username))
            conn.commit()
            
    except Exception as e:
        print(f"Error updating inventory: {e}")
    finally:
        conn.close()

def remove_card(username, card_name):
    conn = get_db_connection()
    c = conn.cursor()
    c.execute("SELECT inventory FROM users WHERE username = ?", (username,))
    row = c.fetchone()
    
    if not row:
        print(f"User '{username}' not found.")
        conn.close()
        return

    try:
        inv = json.loads(row[0])
        plants = inv.get('plants', [])
        zombies = inv.get('zombies', [])
        
        updated = False
        
        if card_name == 'all':
            inv['plants'] = DEFAULT_PLANTS
            inv['zombies'] = DEFAULT_ZOMBIES
            updated = True
            print(f"Reset inventory to defaults for {username}.")
        else:
            if card_name in plants:
                plants.remove(card_name)
                updated = True
                print(f"Removed plant '{card_name}' from {username}.")
            elif card_name in zombies:
                zombies.remove(card_name)
                updated = True
                print(f"Removed zombie '{card_name}' from {username}.")
            else:
                print(f"User does not have card '{card_name}' or card does not exist.")
        
        if updated:
            c.execute("UPDATE users SET inventory = ? WHERE username = ?", (json.dumps(inv), username))
            conn.commit()
            
    except Exception as e:
        print(f"Error updating inventory: {e}")
    finally:
        conn.close()

def edit_level(username, card_name, level):
    conn = get_db_connection()
    c = conn.cursor()
    try:
        c.execute("SELECT plant_levels FROM users WHERE username = ?", (username,))
    except sqlite3.OperationalError:
        print("Error: 'plant_levels' column might not exist. Please run server migration.")
        conn.close()
        return

    row = c.fetchone()
    
    if not row:
        print(f"User '{username}' not found.")
        conn.close()
        return

    try:
        levels_json = row[0]
        if levels_json:
            levels = json.loads(levels_json)
        else:
            levels = {}
        
        try:
            lvl = int(level)
        except ValueError:
            print("Level must be an integer.")
            conn.close()
            return

        if card_name not in ALL_PLANTS:
             print(f"Warning: '{card_name}' is not in the known plant list, but adding anyway.")

        levels[card_name] = lvl
        print(f"Set level of '{card_name}' to {lvl} for user '{username}'.")
        
        c.execute("UPDATE users SET plant_levels = ? WHERE username = ?", (json.dumps(levels), username))
        conn.commit()
            
    except Exception as e:
        print(f"Error updating levels: {e}")
    finally:
        conn.close()

def cancel_user(username):
    conn = get_db_connection()
    c = conn.cursor()
    c.execute("SELECT username FROM users WHERE username = ?", (username,))
    if not c.fetchone():
        print(f"User '{username}' not found.")
        conn.close()
        return

    try:
        c.execute("DELETE FROM users WHERE username = ?", (username,))
        conn.commit()
        print(f"User '{username}' has been deleted.")
    except Exception as e:
        print(f"Error deleting user: {e}")
    finally:
        conn.close()

def set_plant_slot(username, slot_count):
    """设置用户的植物卡槽数量"""
    try:
        slot_count = int(slot_count)
        if slot_count < 1 or slot_count > 50:
            print("Slot count must be between 1 and 50")
            return
    except ValueError:
        print("Slot count must be a valid integer")
        return
    
    conn = get_db_connection()
    c = conn.cursor()
    
    # Check if user exists
    c.execute("SELECT username FROM users WHERE username=?", (username,))
    if not c.fetchone():
        conn.close()
        print(f"User '{username}' not found.")
        return
    
    c.execute("UPDATE users SET plant_slots=? WHERE username=?", (slot_count, username))
    conn.commit()
    conn.close()
    
    print(f"Set plant slots for '{username}' to {slot_count}")

def set_zombie_slot(username, slot_count):
    """设置用户的僵尸卡槽数量"""
    try:
        slot_count = int(slot_count)
        if slot_count < 1 or slot_count > 50:
            print("Slot count must be between 1 and 50")
            return
    except ValueError:
        print("Slot count must be a valid integer")
        return
    
    conn = get_db_connection()
    c = conn.cursor()
    
    # Check if user exists
    c.execute("SELECT username FROM users WHERE username=?", (username,))
    if not c.fetchone():
        conn.close()
        print(f"User '{username}' not found.")
        return
    
    c.execute("UPDATE users SET zombie_slots=? WHERE username=?", (slot_count, username))
    conn.commit()
    conn.close()
    
    print(f"Set zombie slots for '{username}' to {slot_count}")

def main():
    if len(sys.argv) < 2:
        print("Usage:")
        print("  python admin_instr.py query [username]")
        print("  python admin_instr.py add <username> <card_name|all>")
        print("  python admin_instr.py rm <username> <card_name|all>")
        print("  python admin_instr.py editLevel <username> <card_name> <level>")
        print("  python admin_instr.py setPlantSlot <username> <slot_count>")
        print("  python admin_instr.py setZombieSlot <username> <slot_count>")
        print("  python admin_instr.py cancel <username>")
        return

    cmd = sys.argv[1]

    if cmd == 'query':
        if len(sys.argv) == 3:
            query_user(sys.argv[2])
        else:
            query_all()
    elif cmd == 'add':
        if len(sys.argv) != 4:
            print("Usage: python admin_instr.py add <username> <card_name|all>")
            return
        add_card(sys.argv[2], sys.argv[3])
    elif cmd == 'rm':
        if len(sys.argv) != 4:
            print("Usage: python admin_instr.py rm <username> <card_name|all>")
            return
        remove_card(sys.argv[2], sys.argv[3])
    elif cmd == 'editLevel':
        if len(sys.argv) != 5:
            print("Usage: python admin_instr.py editLevel <username> <card_name> <level>")
            return
        edit_level(sys.argv[2], sys.argv[3], sys.argv[4])
    elif cmd == 'setPlantSlot':
        if len(sys.argv) != 4:
            print("Usage: python admin_instr.py setPlantSlot <username> <slot_count>")
            return
        set_plant_slot(sys.argv[2], sys.argv[3])
    elif cmd == 'setZombieSlot':
        if len(sys.argv) != 4:
            print("Usage: python admin_instr.py setZombieSlot <username> <slot_count>")
            return
        set_zombie_slot(sys.argv[2], sys.argv[3])
    elif cmd == 'cancel':
        if len(sys.argv) != 3:
            print("Usage: python admin_instr.py cancel <username>")
            return
        cancel_user(sys.argv[2])
    else:
        print(f"Unknown command: {cmd}")

if __name__ == "__main__":
    main()
