"""
Setup User Groups: Cashier, Accountant, Accounts Clerk, and Superadmin

This script creates four essential user roles with appropriate permissions:
1. Cashier - POS operations, sales recording, receipt printing
2. Accounts Clerk - Transaction posting, invoice creation, data entry
3. Accountant - Approvals, journal entries, financial reporting, reconciliation
4. Superadmin - Full system access and administration
"""

from app.core.database import SessionLocal
from app.models.role import Role, Permission, RolePermission
from app.models.user import User
import uuid


def setup_user_groups():
    db = SessionLocal()

    try:
        print("\n" + "="*80)
        print("USER GROUPS SETUP - CASHIER, ACCOUNTANT, ACCOUNTS CLERK, SUPERADMIN")
        print("="*80 + "\n")

        # ==================== DEFINE ALL PERMISSIONS ====================

        all_permissions = [
            # ==================== POS & SALES ====================
            {'name': 'pos.access', 'description': 'Access POS system', 'module': 'pos', 'action': 'access', 'resource': 'pos_system'},
            {'name': 'pos.record_sale', 'description': 'Record sales transactions', 'module': 'pos', 'action': 'create', 'resource': 'sales'},
            {'name': 'pos.print_receipt', 'description': 'Print receipts', 'module': 'pos', 'action': 'print', 'resource': 'receipts'},
            {'name': 'pos.open_session', 'description': 'Open POS session', 'module': 'pos', 'action': 'open', 'resource': 'session'},
            {'name': 'pos.close_session', 'description': 'Close POS session', 'module': 'pos', 'action': 'close', 'resource': 'session'},
            {'name': 'sales.view', 'description': 'View sales', 'module': 'sales', 'action': 'view', 'resource': 'all'},
            {'name': 'sales.create', 'description': 'Create sales', 'module': 'sales', 'action': 'create', 'resource': 'all'},
            {'name': 'sales.edit', 'description': 'Edit sales', 'module': 'sales', 'action': 'edit', 'resource': 'all'},
            {'name': 'sales.delete', 'description': 'Delete sales', 'module': 'sales', 'action': 'delete', 'resource': 'all'},
            {'name': 'sales.post', 'description': 'Post sales to GL', 'module': 'sales', 'action': 'post', 'resource': 'all'},

            # ==================== INVOICES ====================
            {'name': 'invoices.view', 'description': 'View invoices', 'module': 'invoices', 'action': 'view', 'resource': 'all'},
            {'name': 'invoices.create', 'description': 'Create invoices', 'module': 'invoices', 'action': 'create', 'resource': 'all'},
            {'name': 'invoices.edit', 'description': 'Edit invoices', 'module': 'invoices', 'action': 'edit', 'resource': 'all'},
            {'name': 'invoices.delete', 'description': 'Delete invoices', 'module': 'invoices', 'action': 'delete', 'resource': 'all'},
            {'name': 'invoices.post', 'description': 'Post invoices to GL', 'module': 'invoices', 'action': 'post', 'resource': 'all'},
            {'name': 'invoices.approve', 'description': 'Approve invoices', 'module': 'invoices', 'action': 'approve', 'resource': 'all'},

            # ==================== PURCHASES ====================
            {'name': 'purchases.view', 'description': 'View purchases', 'module': 'purchases', 'action': 'view', 'resource': 'all'},
            {'name': 'purchases.create', 'description': 'Create purchases', 'module': 'purchases', 'action': 'create', 'resource': 'all'},
            {'name': 'purchases.edit', 'description': 'Edit purchases', 'module': 'purchases', 'action': 'edit', 'resource': 'all'},
            {'name': 'purchases.delete', 'description': 'Delete purchases', 'module': 'purchases', 'action': 'delete', 'resource': 'all'},
            {'name': 'purchases.post', 'description': 'Post purchases to GL', 'module': 'purchases', 'action': 'post', 'resource': 'all'},
            {'name': 'purchases.approve', 'description': 'Approve purchases', 'module': 'purchases', 'action': 'approve', 'resource': 'all'},

            # ==================== PAYMENTS & RECEIPTS ====================
            {'name': 'payments.view', 'description': 'View payments', 'module': 'payments', 'action': 'view', 'resource': 'all'},
            {'name': 'payments.create', 'description': 'Create payments', 'module': 'payments', 'action': 'create', 'resource': 'all'},
            {'name': 'payments.edit', 'description': 'Edit payments', 'module': 'payments', 'action': 'edit', 'resource': 'all'},
            {'name': 'payments.delete', 'description': 'Delete payments', 'module': 'payments', 'action': 'delete', 'resource': 'all'},
            {'name': 'payments.approve', 'description': 'Approve payments', 'module': 'payments', 'action': 'approve', 'resource': 'all'},
            {'name': 'receipts.view', 'description': 'View receipts', 'module': 'receipts', 'action': 'view', 'resource': 'all'},
            {'name': 'receipts.create', 'description': 'Create receipts', 'module': 'receipts', 'action': 'create', 'resource': 'all'},
            {'name': 'receipts.post', 'description': 'Post receipts', 'module': 'receipts', 'action': 'post', 'resource': 'all'},

            # ==================== GENERAL LEDGER ====================
            {'name': 'gl.view_entries', 'description': 'View GL entries', 'module': 'general_ledger', 'action': 'view', 'resource': 'entries'},
            {'name': 'gl.create_entry', 'description': 'Create GL entries', 'module': 'general_ledger', 'action': 'create', 'resource': 'entries'},
            {'name': 'gl.edit_entry', 'description': 'Edit GL entries', 'module': 'general_ledger', 'action': 'edit', 'resource': 'entries'},
            {'name': 'gl.delete_entry', 'description': 'Delete GL entries', 'module': 'general_ledger', 'action': 'delete', 'resource': 'entries'},
            {'name': 'gl.post_entry', 'description': 'Post GL entries', 'module': 'general_ledger', 'action': 'post', 'resource': 'entries'},
            {'name': 'gl.view_accounts', 'description': 'View chart of accounts', 'module': 'general_ledger', 'action': 'view', 'resource': 'accounts'},
            {'name': 'gl.manage_accounts', 'description': 'Manage chart of accounts', 'module': 'general_ledger', 'action': 'manage', 'resource': 'accounts'},

            # ==================== FISCAL PERIODS ====================
            {'name': 'fiscal.view_periods', 'description': 'View fiscal periods', 'module': 'fiscal_periods', 'action': 'view', 'resource': 'periods'},
            {'name': 'fiscal.open_period', 'description': 'Open fiscal periods', 'module': 'fiscal_periods', 'action': 'open', 'resource': 'periods'},
            {'name': 'fiscal.close_period', 'description': 'Close fiscal periods', 'module': 'fiscal_periods', 'action': 'close', 'resource': 'periods'},
            {'name': 'fiscal.lock_period', 'description': 'Lock fiscal periods', 'module': 'fiscal_periods', 'action': 'lock', 'resource': 'periods'},
            {'name': 'fiscal.manage_years', 'description': 'Manage fiscal years', 'module': 'fiscal_periods', 'action': 'manage', 'resource': 'years'},

            # ==================== INVENTORY ====================
            {'name': 'inventory.view', 'description': 'View inventory', 'module': 'inventory', 'action': 'view', 'resource': 'all'},
            {'name': 'inventory.create', 'description': 'Create inventory items', 'module': 'inventory', 'action': 'create', 'resource': 'all'},
            {'name': 'inventory.edit', 'description': 'Edit inventory items', 'module': 'inventory', 'action': 'edit', 'resource': 'all'},
            {'name': 'inventory.delete', 'description': 'Delete inventory items', 'module': 'inventory', 'action': 'delete', 'resource': 'all'},
            {'name': 'inventory.adjust', 'description': 'Create inventory adjustments', 'module': 'inventory', 'action': 'adjust', 'resource': 'all'},
            {'name': 'inventory.approve_adjustment', 'description': 'Approve inventory adjustments', 'module': 'inventory', 'action': 'approve', 'resource': 'adjustments'},

            # ==================== CUSTOMERS & SUPPLIERS ====================
            {'name': 'customers.view', 'description': 'View customers', 'module': 'customers', 'action': 'view', 'resource': 'all'},
            {'name': 'customers.create', 'description': 'Create customers', 'module': 'customers', 'action': 'create', 'resource': 'all'},
            {'name': 'customers.edit', 'description': 'Edit customers', 'module': 'customers', 'action': 'edit', 'resource': 'all'},
            {'name': 'customers.delete', 'description': 'Delete customers', 'module': 'customers', 'action': 'delete', 'resource': 'all'},
            {'name': 'suppliers.view', 'description': 'View suppliers', 'module': 'suppliers', 'action': 'view', 'resource': 'all'},
            {'name': 'suppliers.create', 'description': 'Create suppliers', 'module': 'suppliers', 'action': 'create', 'resource': 'all'},
            {'name': 'suppliers.edit', 'description': 'Edit suppliers', 'module': 'suppliers', 'action': 'edit', 'resource': 'all'},
            {'name': 'suppliers.delete', 'description': 'Delete suppliers', 'module': 'suppliers', 'action': 'delete', 'resource': 'all'},

            # ==================== REPORTS ====================
            {'name': 'reports.view_sales', 'description': 'View sales reports', 'module': 'reports', 'action': 'view', 'resource': 'sales_reports'},
            {'name': 'reports.view_financial', 'description': 'View financial reports', 'module': 'reports', 'action': 'view', 'resource': 'financial_reports'},
            {'name': 'reports.view_inventory', 'description': 'View inventory reports', 'module': 'reports', 'action': 'view', 'resource': 'inventory_reports'},
            {'name': 'reports.view_all', 'description': 'View all reports', 'module': 'reports', 'action': 'view', 'resource': 'all_reports'},
            {'name': 'reports.export', 'description': 'Export reports', 'module': 'reports', 'action': 'export', 'resource': 'all'},

            # ==================== SYSTEM ADMINISTRATION ====================
            {'name': 'users.view', 'description': 'View users', 'module': 'users', 'action': 'view', 'resource': 'all'},
            {'name': 'users.create', 'description': 'Create users', 'module': 'users', 'action': 'create', 'resource': 'all'},
            {'name': 'users.edit', 'description': 'Edit users', 'module': 'users', 'action': 'edit', 'resource': 'all'},
            {'name': 'users.delete', 'description': 'Delete users', 'module': 'users', 'action': 'delete', 'resource': 'all'},
            {'name': 'roles.view', 'description': 'View roles', 'module': 'roles', 'action': 'view', 'resource': 'all'},
            {'name': 'roles.manage', 'description': 'Manage roles and permissions', 'module': 'roles', 'action': 'manage', 'resource': 'all'},
            {'name': 'settings.view', 'description': 'View system settings', 'module': 'settings', 'action': 'view', 'resource': 'all'},
            {'name': 'settings.edit', 'description': 'Edit system settings', 'module': 'settings', 'action': 'edit', 'resource': 'all'},
            {'name': 'branches.view', 'description': 'View branches', 'module': 'branches', 'action': 'view', 'resource': 'all'},
            {'name': 'branches.manage', 'description': 'Manage branches', 'module': 'branches', 'action': 'manage', 'resource': 'all'},
            {'name': 'audit.view', 'description': 'View audit logs', 'module': 'audit', 'action': 'view', 'resource': 'all'},
            {'name': 'backup.manage', 'description': 'Manage backups', 'module': 'backup', 'action': 'manage', 'resource': 'all'},
        ]

        # ==================== CREATE/UPDATE PERMISSIONS ====================

        print("📝 Creating/Updating Permissions...")
        permission_map = {}
        created_count = 0
        existing_count = 0

        for perm_data in all_permissions:
            existing_perm = db.query(Permission).filter(
                Permission.name == perm_data['name']
            ).first()

            if existing_perm:
                # Update description if changed
                if existing_perm.description != perm_data['description']:
                    existing_perm.description = perm_data['description']
                permission_map[perm_data['name']] = existing_perm
                existing_count += 1
            else:
                new_perm = Permission(
                    id=str(uuid.uuid4()),
                    **perm_data
                )
                db.add(new_perm)
                db.flush()
                permission_map[perm_data['name']] = new_perm
                created_count += 1

        db.commit()
        print(f"  ✓ {created_count} permissions created, {existing_count} existing")

        # ==================== DEFINE ROLES AND THEIR PERMISSIONS ====================

        role_definitions = {
            'cashier': {
                'description': 'Cashier - POS operations, sales recording, basic customer service',
                'permissions': [
                    # POS & Sales
                    'pos.access', 'pos.record_sale', 'pos.print_receipt',
                    'pos.open_session', 'pos.close_session',
                    'sales.view', 'sales.create',
                    # Customers (read-only for lookup)
                    'customers.view',
                    # Inventory (view only for stock checking)
                    'inventory.view',
                    # Basic receipts
                    'receipts.view', 'receipts.create',
                ]
            },
            'accounts_clerk': {
                'description': 'Accounts Clerk - Transaction posting, invoice creation, data entry, basic reporting',
                'permissions': [
                    # Sales & Invoices
                    'sales.view', 'sales.create', 'sales.edit', 'invoices.view',
                    'invoices.create', 'invoices.edit', 'invoices.post',
                    # Purchases
                    'purchases.view', 'purchases.create', 'purchases.edit', 'purchases.post',
                    # Payments & Receipts
                    'payments.view', 'payments.create', 'receipts.view',
                    'receipts.create', 'receipts.post',
                    # GL (view and create entries)
                    'gl.view_entries', 'gl.create_entry', 'gl.view_accounts',
                    # Inventory
                    'inventory.view', 'inventory.create', 'inventory.edit', 'inventory.adjust',
                    # Customers & Suppliers
                    'customers.view', 'customers.create', 'customers.edit',
                    'suppliers.view', 'suppliers.create', 'suppliers.edit',
                    # Reports (basic)
                    'reports.view_sales', 'reports.view_inventory', 'reports.export',
                    # Fiscal periods (view only)
                    'fiscal.view_periods',
                ]
            },
            'accountant': {
                'description': 'Accountant - Full accounting operations, approvals, financial reporting, reconciliation',
                'permissions': [
                    # Sales & Invoices (full access)
                    'sales.view', 'sales.create', 'sales.edit', 'sales.delete', 'sales.post',
                    'invoices.view', 'invoices.create', 'invoices.edit', 'invoices.delete',
                    'invoices.post', 'invoices.approve',
                    # Purchases (full access with approvals)
                    'purchases.view', 'purchases.create', 'purchases.edit', 'purchases.delete',
                    'purchases.post', 'purchases.approve',
                    # Payments & Receipts (full access with approvals)
                    'payments.view', 'payments.create', 'payments.edit', 'payments.delete',
                    'payments.approve', 'receipts.view', 'receipts.create', 'receipts.post',
                    # General Ledger (full access)
                    'gl.view_entries', 'gl.create_entry', 'gl.edit_entry', 'gl.delete_entry',
                    'gl.post_entry', 'gl.view_accounts', 'gl.manage_accounts',
                    # Fiscal Periods (can open/close but not lock)
                    'fiscal.view_periods', 'fiscal.open_period', 'fiscal.close_period',
                    # Inventory (full access with approvals)
                    'inventory.view', 'inventory.create', 'inventory.edit', 'inventory.delete',
                    'inventory.adjust', 'inventory.approve_adjustment',
                    # Customers & Suppliers (full access)
                    'customers.view', 'customers.create', 'customers.edit', 'customers.delete',
                    'suppliers.view', 'suppliers.create', 'suppliers.edit', 'suppliers.delete',
                    # Reports (all financial reports)
                    'reports.view_sales', 'reports.view_financial', 'reports.view_inventory',
                    'reports.view_all', 'reports.export',
                    # Branches (view only)
                    'branches.view',
                    # Audit logs (view)
                    'audit.view',
                ]
            },
            'superadmin': {
                'description': 'System Administrator - Full system access, user management, system configuration',
                'permissions': [perm['name'] for perm in all_permissions]  # ALL permissions
            }
        }

        # ==================== CREATE/UPDATE ROLES ====================

        print("\n🔐 Creating/Updating Roles...")
        created_roles = {}

        for role_name, role_config in role_definitions.items():
            existing_role = db.query(Role).filter(Role.name == role_name).first()

            if existing_role:
                print(f"  ✓ Role '{role_name}' already exists (ID: {existing_role.id})")
                # Update description
                existing_role.description = role_config['description']
                existing_role.is_system_role = True
                existing_role.is_active = True
                created_roles[role_name] = existing_role
            else:
                new_role = Role(
                    id=str(uuid.uuid4()),
                    name=role_name,
                    description=role_config['description'],
                    is_system_role=True,
                    is_active=True
                )
                db.add(new_role)
                db.flush()
                print(f"  + Created role '{role_name}' (ID: {new_role.id})")
                created_roles[role_name] = new_role

        db.commit()

        # ==================== ASSIGN PERMISSIONS TO ROLES ====================

        print("\n🔗 Assigning Permissions to Roles...")

        for role_name, role_config in role_definitions.items():
            role = created_roles[role_name]

            # Remove existing role permissions
            db.query(RolePermission).filter(RolePermission.role_id == role.id).delete()
            db.flush()

            # Add new permissions
            assigned_count = 0
            for perm_name in role_config['permissions']:
                if perm_name in permission_map:
                    role_perm = RolePermission(
                        id=str(uuid.uuid4()),
                        role_id=role.id,
                        permission_id=permission_map[perm_name].id
                    )
                    db.add(role_perm)
                    assigned_count += 1
                else:
                    print(f"  ⚠️  Permission '{perm_name}' not found for role '{role_name}'")

            print(f"  ✓ {role_name}: {assigned_count} permissions assigned")

        db.commit()

        # ==================== SUMMARY ====================

        print("\n" + "="*80)
        print("SETUP COMPLETE")
        print("="*80)
        print(f"\n📊 Summary:")
        print(f"  • Total Permissions: {len(permission_map)}")
        print(f"  • Roles Created/Updated: {len(created_roles)}")

        print("\n🔐 Roles Summary:")
        for role_name, role_config in role_definitions.items():
            role = created_roles[role_name]
            perm_count = len(role_config['permissions'])
            print(f"\n  [{role_name.upper()}]")
            print(f"    ID: {role.id}")
            print(f"    Description: {role.description}")
            print(f"    Permissions: {perm_count}")

            # Show key permissions for each role
            print(f"    Key Capabilities:")
            if role_name == 'cashier':
                print(f"      • POS operations & sales recording")
                print(f"      • Receipt printing")
                print(f"      • Customer lookup")
            elif role_name == 'accounts_clerk':
                print(f"      • Invoice & purchase creation/posting")
                print(f"      • Payment & receipt processing")
                print(f"      • Basic GL entry creation")
                print(f"      • Data entry & transaction recording")
            elif role_name == 'accountant':
                print(f"      • Full accounting operations")
                print(f"      • Transaction approvals")
                print(f"      • Fiscal period management")
                print(f"      • Financial reporting")
                print(f"      • GL management")
            elif role_name == 'superadmin':
                print(f"      • Complete system access")
                print(f"      • User & role management")
                print(f"      • System configuration")
                print(f"      • Audit log access")

        print("\n💡 Next Steps:")
        print("  1. Create users and assign them to appropriate roles")
        print("  2. Use User.role_id to assign roles (recommended)")
        print("  3. Legacy User.role field still supported for backward compatibility")
        print("  4. Test permissions in the application")

        print("\n📝 Usage Examples:")
        print("  # Assign role to user:")
        print(f"  user.role_id = '{created_roles['cashier'].id}'  # Cashier role")
        print(f"  user.role_id = '{created_roles['accountant'].id}'  # Accountant role")

        print("\n" + "="*80 + "\n")

    except Exception as e:
        db.rollback()
        print(f"\n❌ Error: {str(e)}")
        import traceback
        traceback.print_exc()
    finally:
        db.close()


if __name__ == '__main__':
    setup_user_groups()
