import sqlite3
import os
import tkinter as tk
from tkinter import ttk
import openpyxl  # You'd still need this if you're integrating directly

# Re-using the grouping function from the previous response for context
def group_rows_by_color(excel_file_path):
    """
    Groups rows from an Excel file where each new group starts at a color-filled row.
    (This is a simplified version; refer to the full previous code for details)
    """
    try:
        workbook = openpyxl.load_workbook(excel_file_path)
        sheet = workbook.active

        groups = []
        current_group = []
        
        for row_index, row in enumerate(sheet.iter_rows()):
            first_cell = row[0] 
            is_color_filled_row = False
            if first_cell.fill and first_cell.fill.patternType:
                is_color_filled_row = True

            row_values = [cell.value for cell in row]

            if is_color_filled_row:
                if current_group:
                    groups.append(current_group)
                current_group = [row_values]
            else:
                current_group.append(row_values)

        if current_group:
            groups.append(current_group)

        return groups

    except FileNotFoundError:
        print(f"Error: The file '{excel_file_path}' was not found.")
        return []
    except Exception as e:
        print(f"An error occurred during grouping: {e}")
        return []


def create_and_insert_data_to_db(grouped_data, db_name='my_grouped_data.db'):
    """
    Creates a SQLite database table and inserts the grouped data.

    Args:
        grouped_data (list): A list of lists, where each inner list is a group
                             and contains rows (lists of cell values).
        db_name (str): The name of the SQLite database file.
    """
    conn = None
    try:
        conn = sqlite3.connect(db_name)
        cursor = conn.cursor()

        # --- 1. Create Table ---
        # Define your table schema.
        # You'll need to adapt 'Column1', 'Column2', etc., based on your actual data columns.
        # For simplicity, let's assume a fixed number of columns for each row
        # and add a 'group_id' to link rows to their respective groups.
        
        # Example schema: (adjust based on your actual data structure)
        # You might have a variable number of columns or specific names.
        # This example assumes up to 10 columns per row, and adds a group_id.
        # You should inspect your data to determine the actual number and type of columns.
        
        # To make it flexible, let's assume the first row of your data (e.g., headers) 
        # defines the column count.
        
        # Determine the maximum number of columns across all groups/rows to create a flexible table
        max_cols = 0
        for group in grouped_data:
            for row in group:
                if len(row) > max_cols:
                    max_cols = len(row)
        
        # Create column definitions
        columns_sql = [f"Column{i+1} TEXT" for i in range(max_cols)]
        table_columns = "group_id INTEGER, row_in_group_id INTEGER, " + ", ".join(columns_sql)
        
        cursor.execute(f'''
            CREATE TABLE IF NOT EXISTS grouped_data (
                {table_columns}
            )
        ''')
        conn.commit()
        print(f"Table 'grouped_data' created or already exists in '{db_name}'.")

        # --- 2. Insert Data ---
        for group_id, group in enumerate(grouped_data):
            for row_in_group_id, row_values in enumerate(group):
                # Prepare data for insertion
                # Fill missing columns with None to match the table's max_cols
                padded_row_values = row_values + [None] * (max_cols - len(row_values))
                
                # The values to insert will be group_id, row_in_group_id, then the row_values
                values_to_insert = [group_id, row_in_group_id] + padded_row_values
                
                # Create placeholders for the SQL query
                placeholders = ', '.join(['?'] * len(values_to_insert))
                
                cursor.execute(f'''
                    INSERT INTO grouped_data VALUES ({placeholders})
                ''', values_to_insert)
        
        conn.commit()
        print(f"Successfully inserted {len(grouped_data)} groups into '{db_name}'.")

    except sqlite3.Error as e:
        print(f"SQLite error: {e}")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")
    finally:
        if conn:
            conn.close()

# --- How to use it ---
# 1. First, get your grouped data using the function from earlier:
excel_file_path = 'c:/Users/Todd.SFC/CascadeProjects/data_importer/Buff.xlsx' # Make sure this is the path to your actual .xlsx file
my_grouped_data = group_rows_by_color(excel_file_path)

def view_database_records(db_name='my_project_data.db', max_rows=50):
    """
    View all records from the database in a more readable format.
    
    Args:
        db_name (str): Name of the SQLite database file
        max_rows (int): Maximum number of rows to display per group
    """
    try:
        conn = sqlite3.connect(db_name)
        conn.row_factory = sqlite3.Row  # This allows column access by name
        cursor = conn.cursor()
        
        # Get all table names
        cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
        tables = cursor.fetchall()
        
        for table in tables:
            table_name = table[0]
            print(f"\n{'='*80}")
            print(f"TABLE: {table_name.upper()}")
            print(f"{'='*80}")
            
            # Get column info
            cursor.execute(f"PRAGMA table_info({table_name})")
            columns = [col[1] for col in cursor.fetchall()]
            
            # Get all rows
            cursor.execute(f"SELECT * FROM {table_name}")
            rows = cursor.fetchall()
            
            if not rows:
                print("No records found.")
                continue
                
            # Group data by group_id if it exists
            if 'group_id' in columns:
                groups = {}
                for row in rows:
                    group_id = row['group_id']
                    if group_id not in groups:
                        groups[group_id] = []
                    groups[group_id].append(dict(row))
                
                # Display each group separately
                for group_id, group_rows in groups.items():
                    print(f"\n{'*' * 30} Group {group_id} {'*' * 30}")
                    
                    # Display column headers
                    header = " | ".join(f"{col:15}" for col in columns if col not in ['group_id', 'row_in_group_id'])
                    print(f"\n{' '*3}{header}")
                    print("-" * len(header) * 2)
                    
                    # Display rows
                    for i, row in enumerate(group_rows[:max_rows]):
                        if i > 0 and i % 5 == 0 and i < len(group_rows) - 1:
                            print(f"{' '*3}... {len(group_rows) - i} more rows in group ...")
                            break
                        row_values = [str(row.get(col, ''))[:15].ljust(15) for col in columns 
                                   if col not in ['group_id', 'row_in_group_id']]
                        print(f"{row['row_in_group_id']:2} | {' | '.join(row_values)}")
                    
                    if len(group_rows) > max_rows:
                        print(f"\nShowing first {max_rows} of {len(group_rows)} rows in group")
                    
            else:
                # Display as a simple table if no group_id
                print(f"\n{' | '.join(columns)}\n{'-' * 50}")
                for i, row in enumerate(rows[:max_rows]):
                    if i > 0 and i % 10 == 0 and i < len(rows) - 1:
                        print(f"... {len(rows) - i} more rows ...")
                        break
                    print(" | ".join(str(value)[:30].ljust(30) for value in row))
                
                if len(rows) > max_rows:
                    print(f"\nShowing first {max_rows} of {len(rows)} rows")
                    
            print(f"\nTotal rows in {table_name}: {len(rows)}")
            
    except sqlite3.Error as e:
        print(f"Database error: {e}")
    except Exception as e:
        print(f"An error occurred: {e}")
    finally:
        if conn:
            conn.close()
                



# --- How to use the script ---
if __name__ == "__main__":
    # First, process the Excel file and create the database
    excel_file_path = 'c:/Users/Todd.SFC/CascadeProjects/data_importer/Buff.xlsx'  # Update this to your Excel file path
    my_grouped_data = group_rows_by_color(excel_file_path)
    
    if my_grouped_data:
        db_name = 'my_project_data.db'
        create_and_insert_data_to_db(my_grouped_data, db_name)
        
        # Then view the records
        print("\nViewing database records:")
        view_database_records(db_name)
    else:
        print("No data to process. Please check your Excel file path and contents.")
#     print(row)
# conn.close()
import tkinter as tk
from tkinter import ttk
import sqlite3

def create_gui(db_name='my_project_data.db'):
    """
    Creates a tkinter GUI to view SQLite database records with group selection.
    
    Features:
    - Dropdown to select a specific group
    - Button to show all groups
    - Treeview to display records
    - Auto-refresh capability
    
    Args:
        db_name (str): Name of the SQLite database file
    """
    def refresh_data():
        """Refresh the data from the database and update the UI"""
        # Clear existing items in the tree
        for item in tree.get_children():
            tree.delete(item)
        
        try:
            # Check if database file exists
            db_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', db_name)
            if not os.path.exists(db_path):
                error_msg = f"Database file not found: {db_path}"
                print(error_msg)
                status_label.config(text=error_msg, fg='red')
                return
                
            print(f"Connecting to database: {db_path}")
            conn = sqlite3.connect(db_path)
            conn.row_factory = sqlite3.Row
            cursor = conn.cursor()
            
            # Check if table exists
            table_name = 'grouped_data'
            print(f"Checking for table: {table_name}")
            cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
            all_tables = cursor.fetchall()
            print(f"All tables in database: {all_tables}")
            
            cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name=?", (table_name,))
            if not cursor.fetchone():
                error_msg = f"Table '{table_name}' not found in database. Available tables: {[t[0] for t in all_tables]}"
                print(error_msg)
                status_label.config(text=error_msg, fg='red')
                conn.close()
                return
            
            print(f"Getting table info for: {table_name}")
            cursor.execute(f"PRAGMA table_info({table_name})")
            columns_info = cursor.fetchall()
            print(f"Table columns: {columns_info}")
            columns = [col[1] for col in columns_info]
            print(f"Extracted column names: {columns}")
            
            # Configure tree columns if not already set
            if not tree['columns'] or set(tree['columns']) != set(columns):
                # Clear existing columns
                for col in tree['columns']:
                    tree.heading(col, text='')
                    tree.column(col, width=0, stretch=tk.NO)
                
                # Set new columns
                tree['columns'] = columns
                tree.heading('#0', text='Group')
                tree.column('#0', width=150, minwidth=100, stretch=tk.NO)
                
                for col in columns:
                    tree.heading(col, text=col)
                    tree.column(col, width=100, minwidth=50, stretch=tk.YES)
            
            # Get all rows
            print("Fetching all rows from the table...")
            cursor.execute(f"SELECT * FROM {table_name} ORDER BY group_id, row_in_group_id")
            rows = cursor.fetchall()
            print(f"Fetched {len(rows)} rows from the database")
            
            if not rows:
                print(f"No data found in table '{table_name}'.")
                status_label.config(text=f"No data found in table '{table_name}'", fg='orange')
                conn.close()
                return
            
            # Group rows by group_id
            global all_groups
            all_groups = {}
            for row in rows:
                row_dict = dict(row)  # Convert to dict for easier access
                group_id = row_dict.get('group_id')
                if group_id is not None:
                    if group_id not in all_groups:
                        all_groups[group_id] = []
                    all_groups[group_id].append(row_dict)
            
            print(f"Grouped data into {len(all_groups)} groups")
            
            # Update dropdown with all group IDs
            group_ids = sorted(all_groups.keys(), key=lambda x: int(x) if str(x).isdigit() else float('inf'))
            current_selection = group_selector.get()
            group_selector['values'] = group_ids
            
            # Try to maintain the current selection if it still exists
            if current_selection in group_ids:
                group_selector.set(current_selection)
                show_only_group(current_selection)
            elif group_ids:
                group_selector.set(str(group_ids[0]))
                show_only_group(group_ids[0])
            
            status_label.config(text=f"Loaded {len(rows)} records in {len(group_ids)} groups", fg='green')
            conn.close()
            
        except sqlite3.Error as e:
            error_msg = f"Database error: {e}"
            print(error_msg)
            status_label.config(text=error_msg, fg='red')
        except Exception as e:
            error_msg = f"Unexpected error: {str(e)}"
            print(error_msg)
            status_label.config(text=error_msg, fg='red')
    
    def on_group_selected(event):
        """Handler for group selection change"""
        selected_group = group_selector.get()
        if selected_group:
            # Convert to int if it's a digit, otherwise keep as string
            try:
                group_id = int(selected_group) if selected_group.isdigit() else selected_group
                show_only_group(group_id)
            except Exception as e:
                error_msg = f"Error selecting group: {str(e)}"
                print(error_msg)
                status_label.config(text=error_msg, fg='red')
    
    def show_only_group(group_id):
        """Display only the records from the selected group"""
        # Clear existing items in the tree
        for item in tree.get_children():
            tree.delete(item)
        
        print(f"Attempting to show group: {group_id} (type: {type(group_id)})")
        print(f"Available groups: {list(all_groups.keys())}")
        
        # Try to find a matching group ID (handling both string and int types)
        matching_group_id = None
        for gid in all_groups.keys():
            if str(gid) == str(group_id):
                matching_group_id = gid
                break
        
        if matching_group_id is not None:
            print(f"Found matching group: {matching_group_id} (type: {type(matching_group_id)})")
            # Insert the selected group's data
            group_node = tree.insert('', tk.END, text=f"Group {matching_group_id}", values=[''] * len(tree['columns']))
            for row in all_groups[matching_group_id]:
                # Get values in the correct order based on tree columns
                values = [str(row.get(col, '')) for col in tree['columns']]
                tree.insert(group_node, tk.END, values=values)
            
            # Expand the group
            tree.item(group_node, open=True)
            status_label.config(text=f"Showing group: {matching_group_id}", fg='green')
        else:
            error_msg = f"Group {group_id} not found in available groups"
            print(error_msg)
            status_label.config(text=error_msg, fg='red')
    
    def show_all_groups():
        """Display all groups in the treeview"""
        # Clear existing items in the tree
        for item in tree.get_children():
            tree.delete(item)
        
        if not all_groups:
            status_label.config(text="No groups to display", fg='orange')
            return
        
        # Insert all groups
        for group_id, group_rows in all_groups.items():
            group_node = tree.insert('', tk.END, text=f"Group {group_id}", values=[''] * len(tree['columns']))
            for row in group_rows:
                # Get values in the correct order based on tree columns and ensure they're strings
                values = [str(row.get(col, '')) for col in tree['columns']]
                tree.insert(group_node, tk.END, values=values)
            # Expand all groups
            tree.item(group_node, open=True)
        
        status_label.config(text=f"Showing all {len(all_groups)} groups", fg='green')
    
    # Create main window
    root = tk.Tk()
    root.title("Database Group Viewer")
    root.geometry("1200x800")
    
    # Configure grid weights
    root.grid_rowconfigure(1, weight=1)
    root.grid_columnconfigure(0, weight=1)
    
    # Create controls frame
    controls_frame = tk.Frame(root, padx=5, pady=5)
    controls_frame.grid(row=0, column=0, sticky='ew')
    controls_frame.grid_columnconfigure(1, weight=1)
    
    # Database file label
    db_label = tk.Label(controls_frame, text=f"Database:")
    db_label.grid(row=0, column=0, padx=5, pady=5, sticky='w')
    
    db_path_label = tk.Label(controls_frame, text=db_name, relief='sunken', padx=5, pady=2, width=50, anchor='w')
    db_path_label.grid(row=0, column=1, padx=5, pady=5, sticky='ew')
    
    # Group selection
    group_label = tk.Label(controls_frame, text="Select Group:")
    group_label.grid(row=0, column=2, padx=5, pady=5, sticky='e')
    
    group_selector = ttk.Combobox(controls_frame, state="readonly", width=20)
    group_selector.grid(row=0, column=3, padx=5, pady=5, sticky='w')
    group_selector.bind("<<ComboboxSelected>>", on_group_selected)
    
    # Buttons frame
    button_frame = tk.Frame(controls_frame)
    button_frame.grid(row=0, column=4, padx=10, pady=5, sticky='e')
    
    # Refresh button
    refresh_icon = tk.PhotoImage(width=1, height=1)  # Placeholder for an actual icon
    refresh_button = tk.Button(button_frame, text="🔄 Refresh", command=refresh_data,
                             padx=10, pady=2, compound='left')
    refresh_button.pack(side=tk.LEFT, padx=2)
    
    # Show all groups button
    show_all_button = tk.Button(button_frame, text="Show All Groups", command=show_all_groups,
                              padx=10, pady=2)
    show_all_button.pack(side=tk.LEFT, padx=2)
    
    # Create treeview with scrollbars
    tree_frame = tk.Frame(root)
    tree_frame.grid(row=1, column=0, sticky='nsew', padx=5, pady=(0, 5))
    
    # Vertical scrollbar
    vsb = ttk.Scrollbar(tree_frame, orient="vertical")
    vsb.pack(side='right', fill='y')
    
    # Horizontal scrollbar
    hsb = ttk.Scrollbar(tree_frame, orient="horizontal")
    hsb.pack(side='bottom', fill='x')
    
    # Create treeview
    tree = ttk.Treeview(tree_frame, yscrollcommand=vsb.set, xscrollcommand=hsb.set, selectmode='browse')
    tree.pack(expand=True, fill='both')
    
    # Configure scrollbars
    vsb.config(command=tree.yview)
    hsb.config(command=tree.xview)
    
    # Status bar
    status_frame = tk.Frame(root, height=20, bd=1, relief=tk.SUNKEN)
    status_frame.grid(row=2, column=0, sticky='ew')
    status_frame.grid_columnconfigure(0, weight=1)
    
    status_label = tk.Label(status_frame, text="Ready", anchor='w')
    status_label.pack(side=tk.LEFT, padx=5)
    
    # Initial data load
    global all_groups
    all_groups = {}
    refresh_data()
    
    # Make the window resizable
    root.minsize(800, 600)
    
    root.mainloop()

if __name__ == "__main__":
    create_gui('my_project_data.db')
