"""
Declarative permission catalog for the Megawatt ERP.

This is the single source of truth for the shared Module -> Feature ->
Permission tree. The ``seed_permissions`` management command reads it and
upserts the catalog idempotently, so editing this file and re-running the
command is how you add/adjust fine-grained permissions over time.

Structure::

    MODULES = [
        {
            'code', 'name', 'casl_subject', 'icon', 'description',
            'features': [
                {'code', 'name', 'description', 'actions': [...]},
            ],
        },
    ]

Action verbs come from ``access_control.models`` (view/add/edit/delete/approve).
A permission codename is always ``<module>.<feature>.<action>``.
"""
from .models import (
    ACTION_VIEW, ACTION_ADD, ACTION_EDIT, ACTION_DELETE, ACTION_APPROVE,
)

VIEW = ACTION_VIEW
ADD = ACTION_ADD
EDIT = ACTION_EDIT
DELETE = ACTION_DELETE
APPROVE = ACTION_APPROVE

CRUD = [VIEW, ADD, EDIT, DELETE]


MODULES = [
    {
        'code': 'system_administration',
        'name': 'System Administration',
        'casl_subject': 'SystemAdmin',
        'icon': 'tabler-settings',
        'features': [
            {'code': 'dashboard', 'name': 'Admin Dashboard', 'actions': [VIEW]},
            {'code': 'company_profile', 'name': 'Company Profile', 'actions': [VIEW, EDIT]},
            {'code': 'company_branch', 'name': 'Company Branches', 'actions': CRUD},
            {'code': 'staff_user', 'name': 'Staff User Accounts', 'actions': CRUD},
            {'code': 'roles_permissions', 'name': 'Roles & Permissions', 'actions': CRUD},
            {'code': 'email_settings', 'name': 'Email Settings', 'actions': [VIEW, EDIT]},
            {'code': 'security_settings', 'name': 'Security Settings', 'actions': [VIEW, EDIT]},
            {'code': 'sms_settings', 'name': 'SMS Settings', 'actions': [VIEW, EDIT]},
            {'code': 'notifications', 'name': 'Messages & Notifications', 'actions': [VIEW, EDIT]},
        ],
    },
    {
        'code': 'procurement',
        'name': 'Procurement',
        'casl_subject': 'Procurement',
        'icon': 'tabler-shopping-cart',
        'features': [
            {'code': 'dashboard', 'name': 'Procurement Dashboard', 'actions': [VIEW]},
            {'code': 'supplier', 'name': 'Suppliers', 'actions': CRUD},
            {'code': 'purchase_order', 'name': 'Purchase Orders', 'actions': CRUD + [APPROVE]},
            {'code': 'stock_order', 'name': 'Stock Orders', 'actions': [VIEW, ADD]},
            {'code': 'supplier_payment', 'name': 'Supplier Payments', 'actions': [VIEW, EDIT]},
        ],
    },
    {
        'code': 'warehouse_management',
        'name': 'Warehouse Management',
        'casl_subject': 'Warehouse',
        'icon': 'tabler-building-warehouse',
        'features': [
            {'code': 'dashboard', 'name': 'Warehouse Dashboard', 'actions': [VIEW]},
            {'code': 'warehouse', 'name': 'Warehouses', 'actions': CRUD},
            {'code': 'equipment', 'name': 'Equipment', 'actions': CRUD},
            {'code': 'product_category', 'name': 'Product Categories', 'actions': CRUD},
            {'code': 'product', 'name': 'Products', 'actions': CRUD},
            {'code': 'inventory', 'name': 'Inventory', 'actions': [VIEW, EDIT]},
            {'code': 'stock_transaction', 'name': 'Stock Transactions', 'actions': CRUD},
            {'code': 'purchase_requisition', 'name': 'Purchase Requisitions', 'actions': [VIEW, ADD, APPROVE]},
            {'code': 'stock_requisition', 'name': 'Stock Requisitions', 'actions': [VIEW, ADD, APPROVE]},
            {'code': 'stock_reservation', 'name': 'Stock Reservations', 'actions': [VIEW, ADD, EDIT, APPROVE]},
        ],
    },
    {
        'code': 'finance_and_accounting',
        'name': 'Finance & Accounting',
        'casl_subject': 'Finance',
        'icon': 'tabler-calculator',
        'features': [
            {'code': 'dashboard', 'name': 'Finance Dashboard', 'actions': [VIEW]},
            {'code': 'account', 'name': 'Accounts', 'actions': CRUD},
            {'code': 'chart_of_accounts', 'name': 'Chart of Accounts', 'actions': [VIEW, ADD, EDIT]},
            {'code': 'bank_account', 'name': 'Bank Accounts', 'actions': CRUD},
            {'code': 'expense', 'name': 'Expenses', 'actions': [VIEW, ADD, DELETE]},
            {'code': 'deposit', 'name': 'Deposits', 'actions': [VIEW, ADD, DELETE]},
            {'code': 'asset', 'name': 'Assets', 'actions': CRUD},
            {'code': 'loan_portfolio', 'name': 'Loan Portfolios', 'actions': CRUD},
            {'code': 'dividend', 'name': 'Dividends', 'actions': CRUD},
            {'code': 'customer_order_finance', 'name': 'Customer Order Approval', 'actions': [VIEW, EDIT, APPROVE]},
            {'code': 'purchase_order_finance', 'name': 'Purchase Order Approval', 'actions': [VIEW, APPROVE]},
            {'code': 'payroll_finance', 'name': 'Payroll (Finance)', 'actions': [VIEW, EDIT]},
            {'code': 'manual_journal', 'name': 'Manual Journal Entries', 'actions': CRUD + [APPROVE]},
            {'code': 'account_mapping', 'name': 'Account Mappings', 'actions': [VIEW, ADD, DELETE]},
            {'code': 'financial_reports', 'name': 'Financial Reports', 'actions': [VIEW]},
        ],
    },
    {
        'code': 'human_resource',
        'name': 'Human Resource',
        'casl_subject': 'HumanResource',
        'icon': 'tabler-users',
        'features': [
            {'code': 'dashboard', 'name': 'HR Dashboard', 'actions': [VIEW]},
            {'code': 'staff_profile', 'name': 'Staff Profiles', 'actions': CRUD},
            {'code': 'staff_position', 'name': 'Staff Positions', 'actions': CRUD},
            {'code': 'bonus', 'name': 'Bonuses', 'actions': CRUD},
            {'code': 'deduction', 'name': 'Deductions', 'actions': CRUD},
            {'code': 'work_shift', 'name': 'Work Shifts', 'actions': CRUD},
            {'code': 'staff_leave', 'name': 'Staff Leave', 'actions': [VIEW, ADD, EDIT, APPROVE]},
            {'code': 'payroll_sheet', 'name': 'Payroll Sheets', 'actions': CRUD},
            {'code': 'educational_qualification', 'name': 'Educational Qualifications', 'actions': [VIEW, ADD, EDIT]},
            {'code': 'training_record', 'name': 'Training Records', 'actions': [VIEW, ADD, EDIT]},
            {'code': 'disciplinary_record', 'name': 'Disciplinary Records', 'actions': [VIEW, ADD]},
            {'code': 'task', 'name': 'Tasks & Engagements', 'actions': [VIEW, ADD]},
            {'code': 'vacancy', 'name': 'Vacancies', 'actions': [VIEW, ADD]},
            {'code': 'employee_advance', 'name': 'Employee Advances', 'actions': [VIEW, ADD, EDIT]},
            {'code': 'employment_status', 'name': 'Employment Status', 'actions': [VIEW, EDIT]},
            {'code': 'payslip', 'name': 'Payslips & P9', 'actions': [VIEW]},
        ],
    },
    {
        'code': 'sales_and_marketing',
        'name': 'Sales & Marketing',
        'casl_subject': 'Sales',
        'icon': 'tabler-businessplan',
        'features': [
            {'code': 'dashboard', 'name': 'Sales Dashboard', 'actions': [VIEW]},
            {'code': 'customer', 'name': 'Customers', 'actions': CRUD},
            {'code': 'product_catalog', 'name': 'Product Catalog', 'actions': [VIEW, EDIT]},
            {'code': 'sale_outlet', 'name': 'Sale Outlets', 'actions': [VIEW, ADD]},
            {'code': 'quotation', 'name': 'Quotations', 'actions': CRUD + [APPROVE]},
            {'code': 'customer_order', 'name': 'Customer Orders', 'actions': CRUD},
            {'code': 'customer_order_payment', 'name': 'Customer Order Payments', 'actions': [VIEW, ADD]},
            {'code': 'landed_cost', 'name': 'Landed Costs', 'actions': CRUD},
            {'code': 'purchase_order_sales', 'name': 'Purchase Orders (Sales)', 'actions': [VIEW, ADD, DELETE]},
            {'code': 'customer_document', 'name': 'Customer Documents', 'actions': [VIEW, ADD, DELETE]},
            {'code': 'agent_orders', 'name': 'Agent Orders', 'actions': [VIEW]},
            {'code': 'performance_dashboard', 'name': 'Performance Dashboards', 'actions': [VIEW]},
        ],
    },
    {
        'code': 'reports',
        'name': 'Reports',
        'casl_subject': 'Reports',
        'icon': 'tabler-report',
        'features': [
            {'code': 'warehouse_reports', 'name': 'Warehouse Reports', 'actions': [VIEW]},
            {'code': 'procurement_reports', 'name': 'Procurement Reports', 'actions': [VIEW]},
        ],
    },
]


# Default per-company roles created during back-fill. Each maps to a set of
# permission codenames (or the wildcard '*' meaning every permission). The
# back-fill migration also assigns these to existing staff based on their
# department + legacy flags so nobody loses access on rollout.
def _module_codenames(module_code, actions=None):
    """All catalog codenames for a module, optionally filtered by action."""
    result = []
    for module in MODULES:
        if module['code'] != module_code:
            continue
        for feature in module['features']:
            for action in feature['actions']:
                if actions is None or action in actions:
                    result.append(f"{module['code']}.{feature['code']}.{action}")
    return result


def all_codenames():
    return [
        f"{m['code']}.{f['code']}.{a}"
        for m in MODULES for f in m['features'] for a in f['actions']
    ]


# Department string (CompanyDepartment.department_name) -> module code.
DEPARTMENT_TO_MODULE = {
    'system_and_administration': 'system_administration',
    'procurement': 'procurement',
    'warehouse_management': 'warehouse_management',
    'finance_and_accounting': 'finance_and_accounting',
    'human_resource_management': 'human_resource',
    'sales': 'sales_and_marketing',
    'marketing': 'sales_and_marketing',
}
