"""
Seed default roles and permissions for the Nexa platform.

Usage:
    python manage.py seed_permissions
    python manage.py seed_permissions --reset   # Delete existing and reseed
"""
import logging

from django.core.management.base import BaseCommand
from django.db import transaction

from apps.core.permission.models import (
    Permission, PermissionAction, Role, RolePermission, RAICPolicy,
)

logger = logging.getLogger('apps')


# ──────────────────────────────────────────────────────────────
# Persian label maps — used by grouped endpoint too
# ──────────────────────────────────────────────────────────────
MODULE_LABELS = {
    'platform': 'پلتفرم',
    'hrm': 'منابع انسانی',
    'pm': 'مدیریت پروژه',
    'ppm': 'مدیریت پرتفولیو و برنامه',
    'inventory': 'انبار و موجودی',
    'scm': 'خرید و تدارکات',
    'clm': 'مدیریت قراردادها',
    'notification': 'اطلاع‌رسانی',
    'workflow': 'گردش کار',
    'worktable': 'جداول داینامیک',
    'document_control': 'مدیریت اسناد',
    'strategy': 'مدیریت راهبرد و حاکمیت',
}

RESOURCE_LABELS = {
    # ── پلتفرم ──
    'user': 'کاربر',
    'role': 'نقش',
    'permission': 'دسترسی',
    'audit': 'لاگ بازرسی',
    'org_unit': 'واحد سازمانی',
    'company': 'شرکت',
    'module_settings': 'تنظیمات ماژول',
    'data_policy': 'سیاست داده',

    # ── منابع انسانی ──
    'employee': 'پرسنل',
    'position': 'سمت',
    'job_family': 'خانواده شغلی',
    'job_title': 'عنوان شغلی',
    'legal_entity': 'شخصیت حقوقی',
    'location': 'موقعیت مکانی',
    'reporting_line': 'خط گزارش‌دهی',
    'employment_record': 'سوابق استخدام',
    'employee_document': 'مدارک پرسنل',
    'work_schedule': 'برنامه کاری',
    'shift_pattern': 'الگوی شیفت',
    'timesheet': 'تایم‌شیت',
    'attendance': 'حضور و غیاب',
    'leave_policy': 'سیاست مرخصی',
    'leave_balance': 'مانده مرخصی',
    'leave_request': 'درخواست مرخصی',
    'pay_grade': 'رتبه حقوقی',
    'compensation': 'حقوق و مزایا',
    'bank_account': 'حساب بانکی',

    # ── مدیریت پروژه ──
    'project': 'پروژه',
    'task': 'فعالیت',
    'dependency': 'وابستگی',
    'resource': 'منبع',
    'resource_assignment': 'تخصیص منبع',
    'budget': 'بودجه',
    'cost_entry': 'هزینه',
    'risk': 'ریسک',
    'baseline': 'خط مبنا',
    'calendar': 'تقویم',
    'holiday': 'تعطیلات',
    'change_request': 'درخواست تغییر',
    'project_member': 'عضو پروژه',
    'comment': 'نظر',
    'activity_log': 'لاگ فعالیت',
    'task_label': 'برچسب فعالیت',
    'raci': 'ماتریس RACI',
    'kanban': 'کانبان',
    'project_template': 'قالب پروژه',
    'issue': 'مسئله',
    'obs': 'ساختار شکست سازمانی',
    'rbs': 'ساختار شکست منابع',
    'quality_plan': 'طرح کیفیت',
    'ncr': 'عدم انطباق',
    'quality_checklist': 'چک‌لیست کیفیت',
    'project_document': 'مستندات پروژه',

    # ── انبار و موجودی ──
    'item': 'کالا',
    'item_type': 'نوع کالا',
    'item_group': 'گروه کالا',
    'uom': 'واحد اندازه‌گیری',
    'warehouse': 'انبار',
    'storage_location': 'محل نگهداری',
    'stock': 'موجودی',
    'batch': 'بچ',
    'serial_number': 'شماره سریال',
    'costing': 'هزینه‌یابی',
    'reservation': 'رزرو',
    'physical_inventory': 'انبارگردانی',
    'inspection': 'بازرسی کیفیت',

    # ── خرید و تدارکات ──
    'vendor': 'تامین‌کننده',
    'vendor_category': 'دسته تامین‌کننده',
    'purchase_requisition': 'درخواست خرید',
    'rfq': 'استعلام بها',
    'purchase_order': 'سفارش خرید',
    'goods_receipt': 'رسید کالا',
    'purchase_return': 'مرجوعی خرید',
    'vendor_evaluation': 'ارزیابی تامین‌کننده',
    'price_list': 'لیست قیمت',

    # ── مدیریت قراردادها ──
    'contract': 'قرارداد',
    'contract_template': 'قالب قرارداد',
    'contract_party': 'طرف قرارداد',
    'contract_clause': 'بند قرارداد',
    'contract_milestone': 'نقطه عطف قرارداد',
    'contract_amendment': 'الحاقیه',
    'contract_renewal': 'تمدید قرارداد',

    # ── سرویس‌ها ──
    'notification_template': 'قالب اطلاع‌رسانی',
    'notification_category': 'دسته اطلاع‌رسانی',
    'notification': 'اطلاع‌رسانی',
    'process_definition': 'تعریف فرآیند',
    'process_instance': 'نمونه فرآیند',
    'workflow_task': 'وظیفه گردش کار',
    'sla': 'SLA',
    'worktable': 'جدول داینامیک',
    'worktable_record': 'رکورد جدول',

    # ── مدیریت اسناد ──
    'document_category': 'دسته اسناد',
    'document': 'سند',
    'document_version': 'نسخه سند',
    'document_approval': 'تأیید سند',
    'document_access': 'دسترسی سند',

    # ── پرتفولیو و برنامه ──
    'portfolio': 'پرتفولیو',
    'program': 'برنامه',
    'program_project': 'پروژه برنامه',
    'business_case': 'کیس تجاری',
    'scoring_model': 'مدل امتیازدهی',
    'benefit_plan': 'طرح منافع',
    'capacity_plan': 'طرح ظرفیت',
    'cross_project_dependency': 'وابستگی بین پروژه‌ای',
    'ppm_document': 'سند PPM',

    # ── مدیریت راهبرد ──
    'vision': 'چشم‌انداز',
    'strategic_theme': 'محور راهبردی',
    'objective': 'هدف',
    'key_result': 'نتیجه کلیدی',
    'check_in': 'ثبت پیشرفت',
    'kpi_definition': 'تعریف KPI',
    'kpi_target': 'هدف KPI',
    'kpi_actual': 'مقدار واقعی KPI',
    'kpi_assignment': 'تخصیص KPI',
    'strategy_map': 'نقشه راهبرد',
    'scorecard': 'کارت امتیازی',
    'gate_process': 'فرآیند Gate',
    'gate': 'گیت',
    'gate_review': 'بازبینی گیت',
    'policy': 'سیاست سازمانی',
    'alignment': 'همسویی راهبردی',
}

ACTION_LABELS = {
    'create': 'ایجاد',
    'read': 'مشاهده',
    'update': 'ویرایش',
    'delete': 'حذف',
    'list': 'لیست',
    'export': 'خروجی',
    'import': 'ورودی',
    'approve': 'تایید',
    'reject': 'رد',
    'assign': 'تخصیص',
    'manage': 'مدیریت کامل',
    'resolve': 'حل مسئله',
}


def _perm_name(resource_key: str, action: str) -> str:
    """Generate Persian permission name: 'ایجاد پرسنل'."""
    action_fa = ACTION_LABELS.get(action, action)
    resource_fa = RESOURCE_LABELS.get(resource_key, resource_key)
    return f'{action_fa} {resource_fa}'


def _crud(module: str, resource: str, sensitive_delete: bool = True):
    """Generate standard CRUD+list permissions for a resource."""
    return [
        (module, resource, 'create', _perm_name(resource, 'create'), False),
        (module, resource, 'read', _perm_name(resource, 'read'), False),
        (module, resource, 'update', _perm_name(resource, 'update'), False),
        (module, resource, 'delete', _perm_name(resource, 'delete'), sensitive_delete),
        (module, resource, 'list', _perm_name(resource, 'list'), False),
    ]


def _crud_export(module: str, resource: str, sensitive_delete: bool = True):
    """CRUD+list+export."""
    return _crud(module, resource, sensitive_delete) + [
        (module, resource, 'export', _perm_name(resource, 'export'), False),
    ]


# ──────────────────────────────────────────────────────────────
# Permission Definitions: (module, resource, action, name, is_sensitive)
# ──────────────────────────────────────────────────────────────
PLATFORM_PERMISSIONS = [
    # ── پلتفرم / مدیریت کاربران ──
    *_crud('platform', 'user'),
    ('platform', 'user', 'manage', _perm_name('user', 'manage'), True),

    # ── پلتفرم / نقش‌ها ──
    *_crud('platform', 'role'),
    ('platform', 'role', 'assign', _perm_name('role', 'assign'), True),

    # ── پلتفرم / دسترسی‌ها ──
    ('platform', 'permission', 'read', _perm_name('permission', 'read'), False),
    ('platform', 'permission', 'list', _perm_name('permission', 'list'), False),

    # ── پلتفرم / لاگ بازرسی ──
    ('platform', 'audit', 'read', _perm_name('audit', 'read'), True),
    ('platform', 'audit', 'list', _perm_name('audit', 'list'), True),

    # ── پلتفرم / واحد سازمانی ──
    *_crud('platform', 'org_unit'),

    # ── پلتفرم / شرکت ──
    *_crud('platform', 'company'),

    # ── پلتفرم / تنظیمات ماژول ──
    ('platform', 'module_settings', 'read', _perm_name('module_settings', 'read'), False),
    ('platform', 'module_settings', 'update', _perm_name('module_settings', 'update'), True),

    # ── پلتفرم / سیاست داده ──
    *_crud('platform', 'data_policy'),
]

MODULE_PERMISSIONS = {
    # ═══════════════════════════════════════════════════════════
    # منابع انسانی (HRM)
    # ═══════════════════════════════════════════════════════════
    'hrm': [
        # ساختار سازمانی
        *_crud('hrm', 'legal_entity'),
        *_crud('hrm', 'location'),
        *_crud('hrm', 'reporting_line'),

        # اطلاعات پایه پرسنل
        *_crud_export('hrm', 'employee'),
        ('hrm', 'employee', 'import', _perm_name('employee', 'import'), False),
        *_crud('hrm', 'employment_record'),
        *_crud('hrm', 'employee_document'),
        *_crud('hrm', 'bank_account'),

        # سمت و شغل
        *_crud('hrm', 'position'),
        ('hrm', 'position', 'assign', _perm_name('position', 'assign'), False),
        *_crud('hrm', 'job_family'),
        *_crud('hrm', 'job_title'),

        # زمان و حضور
        *_crud('hrm', 'work_schedule'),
        *_crud('hrm', 'shift_pattern'),
        *_crud_export('hrm', 'timesheet'),
        ('hrm', 'timesheet', 'approve', _perm_name('timesheet', 'approve'), False),
        *_crud('hrm', 'attendance'),

        # مرخصی
        *_crud('hrm', 'leave_policy'),
        *_crud('hrm', 'leave_balance'),
        *_crud('hrm', 'leave_request'),
        ('hrm', 'leave_request', 'approve', _perm_name('leave_request', 'approve'), False),
        ('hrm', 'leave_request', 'reject', _perm_name('leave_request', 'reject'), False),

        # حقوق و مزایا
        *_crud('hrm', 'pay_grade'),
        *_crud('hrm', 'compensation'),
    ],

    # ═══════════════════════════════════════════════════════════
    # مدیریت پروژه (PM)
    # ═══════════════════════════════════════════════════════════
    'pm': [
        # پروژه
        *_crud_export('pm', 'project'),
        ('pm', 'project', 'approve', _perm_name('project', 'approve'), False),

        # فعالیت
        *_crud_export('pm', 'task'),
        ('pm', 'task', 'assign', _perm_name('task', 'assign'), False),
        ('pm', 'task', 'approve', _perm_name('task', 'approve'), False),

        # وابستگی و منابع
        *_crud('pm', 'dependency'),
        *_crud('pm', 'resource'),
        *_crud('pm', 'resource_assignment'),

        # مالی
        *_crud('pm', 'budget'),
        ('pm', 'budget', 'approve', _perm_name('budget', 'approve'), False),
        *_crud('pm', 'cost_entry'),

        # ریسک
        *_crud('pm', 'risk'),

        # خط مبنا
        *_crud('pm', 'baseline'),

        # تقویم
        *_crud('pm', 'calendar'),
        *_crud('pm', 'holiday'),

        # درخواست تغییر
        *_crud('pm', 'change_request'),
        ('pm', 'change_request', 'approve', _perm_name('change_request', 'approve'), False),
        ('pm', 'change_request', 'reject', _perm_name('change_request', 'reject'), False),

        # اعضا و مشارکت
        *_crud('pm', 'project_member'),
        *_crud('pm', 'comment', False),
        ('pm', 'activity_log', 'read', _perm_name('activity_log', 'read'), False),
        ('pm', 'activity_log', 'list', _perm_name('activity_log', 'list'), False),

        # برچسب و RACI
        *_crud('pm', 'task_label'),
        *_crud('pm', 'raci'),

        # کانبان
        ('pm', 'kanban', 'read', _perm_name('kanban', 'read'), False),
        ('pm', 'kanban', 'update', _perm_name('kanban', 'update'), False),

        # قالب پروژه
        *_crud('pm', 'project_template'),

        # تایم‌شیت PM
        *_crud('pm', 'timesheet'),

        # مسائل (Issue Log)
        *_crud('pm', 'issue'),
        ('pm', 'issue', 'assign', _perm_name('issue', 'assign'), False),
        ('pm', 'issue', 'resolve', _perm_name('issue', 'resolve'), False),

        # ساختار شکست سازمانی (OBS)
        *_crud('pm', 'obs'),

        # ساختار شکست منابع (RBS)
        *_crud('pm', 'rbs'),

        # مدیریت کیفیت (Quality Management)
        *_crud('pm', 'quality_plan'),
        *_crud('pm', 'inspection'),
        *_crud('pm', 'ncr'),
        *_crud('pm', 'quality_checklist'),

        # مستندات پروژه (Document Control Integration)
        *_crud('pm', 'project_document'),
    ],

    # ═══════════════════════════════════════════════════════════
    # انبار و موجودی (Inventory)
    # ═══════════════════════════════════════════════════════════
    'inventory': [
        # داده پایه
        *_crud('inventory', 'item_type'),
        *_crud('inventory', 'item_group'),
        *_crud('inventory', 'uom'),
        *_crud_export('inventory', 'item'),
        ('inventory', 'item', 'import', _perm_name('item', 'import'), False),

        # انبار
        *_crud('inventory', 'warehouse'),
        *_crud('inventory', 'storage_location'),

        # موجودی
        ('inventory', 'stock', 'read', _perm_name('stock', 'read'), False),
        ('inventory', 'stock', 'list', _perm_name('stock', 'list'), False),
        ('inventory', 'stock', 'export', _perm_name('stock', 'export'), False),
        ('inventory', 'stock', 'create', _perm_name('stock', 'create'), False),
        ('inventory', 'stock', 'update', _perm_name('stock', 'update'), False),

        # بچ و سریال
        *_crud('inventory', 'batch'),
        *_crud('inventory', 'serial_number'),

        # هزینه‌یابی
        ('inventory', 'costing', 'read', _perm_name('costing', 'read'), False),
        ('inventory', 'costing', 'update', _perm_name('costing', 'update'), False),
        ('inventory', 'costing', 'list', _perm_name('costing', 'list'), False),

        # رزرو
        *_crud('inventory', 'reservation'),

        # انبارگردانی
        *_crud('inventory', 'physical_inventory'),
        ('inventory', 'physical_inventory', 'approve', _perm_name('physical_inventory', 'approve'), False),

        # بازرسی کیفیت
        *_crud('inventory', 'inspection'),
        ('inventory', 'inspection', 'approve', _perm_name('inspection', 'approve'), False),
    ],

    # ═══════════════════════════════════════════════════════════
    # خرید و تدارکات (SCM)
    # ═══════════════════════════════════════════════════════════
    'scm': [
        # تامین‌کننده
        *_crud_export('scm', 'vendor'),
        ('scm', 'vendor', 'import', _perm_name('vendor', 'import'), False),
        *_crud('scm', 'vendor_category'),

        # درخواست خرید
        *_crud('scm', 'purchase_requisition'),
        ('scm', 'purchase_requisition', 'approve', _perm_name('purchase_requisition', 'approve'), False),
        ('scm', 'purchase_requisition', 'reject', _perm_name('purchase_requisition', 'reject'), False),

        # استعلام بها
        *_crud('scm', 'rfq'),
        ('scm', 'rfq', 'approve', _perm_name('rfq', 'approve'), False),

        # سفارش خرید
        *_crud_export('scm', 'purchase_order'),
        ('scm', 'purchase_order', 'approve', _perm_name('purchase_order', 'approve'), False),
        ('scm', 'purchase_order', 'reject', _perm_name('purchase_order', 'reject'), False),

        # رسید کالا
        *_crud('scm', 'goods_receipt'),
        ('scm', 'goods_receipt', 'approve', _perm_name('goods_receipt', 'approve'), False),

        # مرجوعی
        *_crud('scm', 'purchase_return'),
        ('scm', 'purchase_return', 'approve', _perm_name('purchase_return', 'approve'), False),

        # ارزیابی تامین‌کننده
        *_crud('scm', 'vendor_evaluation'),

        # لیست قیمت
        *_crud('scm', 'price_list'),
    ],

    # ═══════════════════════════════════════════════════════════
    # مدیریت قراردادها (CLM)
    # ═══════════════════════════════════════════════════════════
    'clm': [
        *_crud_export('clm', 'contract'),
        ('clm', 'contract', 'approve', _perm_name('contract', 'approve'), False),
        ('clm', 'contract', 'reject', _perm_name('contract', 'reject'), False),
        *_crud('clm', 'contract_template'),
        *_crud('clm', 'contract_party'),
        *_crud('clm', 'contract_clause'),
        *_crud('clm', 'contract_milestone'),
        ('clm', 'contract_milestone', 'approve', _perm_name('contract_milestone', 'approve'), False),
        *_crud('clm', 'contract_amendment'),
        ('clm', 'contract_amendment', 'approve', _perm_name('contract_amendment', 'approve'), False),
        *_crud('clm', 'contract_renewal'),
    ],

    # ═══════════════════════════════════════════════════════════
    # سرویس اطلاع‌رسانی (Notification)
    # ═══════════════════════════════════════════════════════════
    'notification': [
        *_crud('notification', 'notification_category'),
        *_crud('notification', 'notification_template'),
        ('notification', 'notification', 'read', _perm_name('notification', 'read'), False),
        ('notification', 'notification', 'list', _perm_name('notification', 'list'), False),
        ('notification', 'notification', 'create', _perm_name('notification', 'create'), False),
    ],

    # ═══════════════════════════════════════════════════════════
    # سرویس گردش کار (Workflow)
    # ═══════════════════════════════════════════════════════════
    'workflow': [
        *_crud('workflow', 'process_definition'),
        *_crud('workflow', 'process_instance'),
        *_crud('workflow', 'workflow_task'),
        ('workflow', 'workflow_task', 'assign', _perm_name('workflow_task', 'assign'), False),
        ('workflow', 'workflow_task', 'approve', _perm_name('workflow_task', 'approve'), False),
        *_crud('workflow', 'sla'),
    ],

    # ═══════════════════════════════════════════════════════════
    # جداول داینامیک (Worktable)
    # ═══════════════════════════════════════════════════════════
    'worktable': [
        *_crud('worktable', 'worktable'),
        ('worktable', 'worktable', 'export', _perm_name('worktable', 'export'), False),
        ('worktable', 'worktable', 'import', _perm_name('worktable', 'import'), False),
        *_crud('worktable', 'worktable_record'),
    ],

    # ═══════════════════════════════════════════════════════════
    # مدیریت اسناد (Document Control)
    # ═══════════════════════════════════════════════════════════
    'document_control': [
        *_crud('document_control', 'document_category'),
        *_crud('document_control', 'document'),
        ('document_control', 'document', 'approve', _perm_name('document', 'approve'), False),
        ('document_control', 'document', 'export', _perm_name('document', 'export'), False),
        *_crud('document_control', 'document_version'),
        *_crud('document_control', 'document_approval'),
        ('document_control', 'document_approval', 'approve', _perm_name('document_approval', 'approve'), True),
        *_crud('document_control', 'document_access'),
    ],

    # ═════════════════════════════════════════════════════════
    # مدیریت پرتفولیو و برنامه (PPM)
    # ═════════════════════════════════════════════════════════
    'ppm': [
        # پرتفولیو
        *_crud_export('ppm', 'portfolio'),

        # برنامه
        *_crud_export('ppm', 'program'),
        *_crud('ppm', 'program_project'),

        # کیس تجاری
        *_crud('ppm', 'business_case'),
        ('ppm', 'business_case', 'approve', _perm_name('business_case', 'approve'), False),
        ('ppm', 'business_case', 'reject', _perm_name('business_case', 'reject'), False),

        # امتیازدهی
        *_crud('ppm', 'scoring_model'),

        # منافع
        *_crud('ppm', 'benefit_plan'),

        # ظرفیت‌سنجی
        *_crud('ppm', 'capacity_plan'),

        # وابستگی بین پروژه‌ای
        *_crud('ppm', 'cross_project_dependency'),

        # اسناد PPM
        *_crud('ppm', 'ppm_document'),
    ],

    # ═════════════════════════════════════════════════════════
    # مدیریت راهبرد و حاکمیت (Strategy)
    # ═════════════════════════════════════════════════════════
    'strategy': [
        # چشم‌انداز و محورهای راهبردی
        *_crud('strategy', 'vision'),
        *_crud('strategy', 'strategic_theme'),

        # OKR
        *_crud('strategy', 'objective'),
        *_crud('strategy', 'key_result'),
        *_crud('strategy', 'check_in'),

        # KPI
        *_crud('strategy', 'kpi_definition'),
        *_crud('strategy', 'kpi_target'),
        *_crud('strategy', 'kpi_actual'),
        *_crud('strategy', 'kpi_assignment'),

        # نقشه راهبرد
        *_crud('strategy', 'strategy_map'),

        # کارت امتیازی متوازن
        *_crud('strategy', 'scorecard'),

        # Stage-Gate
        *_crud('strategy', 'gate_process'),
        *_crud('strategy', 'gate'),
        *_crud('strategy', 'gate_review'),
        ('strategy', 'gate_review', 'approve', _perm_name('gate_review', 'approve'), False),
        ('strategy', 'gate_review', 'reject', _perm_name('gate_review', 'reject'), False),

        # سیاست سازمانی
        *_crud('strategy', 'policy'),
        ('strategy', 'policy', 'approve', _perm_name('policy', 'approve'), False),

        # همسویی راهبردی
        *_crud('strategy', 'alignment'),
    ],
}


# ──────────────────────────────────────────────────────────────
# Role Definitions
# ──────────────────────────────────────────────────────────────
ROLES = {
    'super_admin': {
        'name': 'مدیر ارشد سیستم',
        'description': 'دسترسی کامل به تمام بخش‌ها',
        'is_system': True,
        'permissions': '__all__',
    },
    'admin': {
        'name': 'مدیر سیستم',
        'description': 'مدیریت کاربران، نقش‌ها و تنظیمات پلتفرم',
        'is_system': True,
        'permissions': [
            'platform.*',
        ],
    },
    'manager': {
        'name': 'مدیر',
        'description': 'دسترسی مدیریتی به ماژول‌ها (بدون تنظیمات پلتفرم)',
        'is_system': True,
        'permissions': [
            '*.*.read',
            '*.*.list',
            '*.*.create',
            '*.*.update',
            '*.*.export',
            '*.*.approve',
            '*.*.assign',
        ],
    },
    'employee': {
        'name': 'کارمند',
        'description': 'دسترسی پایه — مشاهده و ایجاد در حد مجاز',
        'is_system': True,
        'permissions': [
            '*.*.read',
            '*.*.list',
            'pm.task.create',
            'pm.comment.create',
            'hrm.leave_request.create',
        ],
    },
    'hr_manager': {
        'name': 'مدیر منابع انسانی',
        'description': 'دسترسی کامل به ماژول منابع انسانی',
        'is_system': True,
        'permissions': [
            'hrm.*',
        ],
    },
    'project_manager': {
        'name': 'مدیر پروژه',
        'description': 'دسترسی کامل به ماژول مدیریت پروژه',
        'is_system': True,
        'permissions': [
            'pm.*',
        ],
    },
    'warehouse_manager': {
        'name': 'مدیر انبار',
        'description': 'دسترسی کامل به ماژول انبار و موجودی',
        'is_system': True,
        'permissions': [
            'inventory.*',
        ],
    },
    'procurement_manager': {
        'name': 'مدیر خرید و تدارکات',
        'description': 'دسترسی کامل به ماژول خرید و تدارکات',
        'is_system': True,
        'permissions': [
            'scm.*',
        ],
    },
    'contract_manager': {
        'name': 'مدیر قراردادها',
        'description': 'دسترسی کامل به ماژول مدیریت قراردادها',
        'is_system': True,
        'permissions': [
            'clm.*',
        ],
    },
    'strategy_manager': {
        'name': 'مدیر راهبرد',
        'description': 'دسترسی کامل به ماژول مدیریت راهبرد و حاکمیت',
        'is_system': True,
        'permissions': [
            'strategy.*',
        ],
    },
    'ppm_manager': {
        'name': 'مدیر پرتفولیو',
        'description': 'دسترسی کامل به ماژول پرتفولیو و برنامه',
        'is_system': True,
        'permissions': [
            'ppm.*',
        ],
    },
}


# ──────────────────────────────────────────────────────────────
# RAIC Policies (default relationship-based access)
# ──────────────────────────────────────────────────────────────
RAIC_DEFAULTS = [
    # (module, object_type, relation_type, permission_codename)
    ('pm', 'pm.task', 'creator', 'pm.task.update'),
    ('pm', 'pm.task', 'creator', 'pm.task.delete'),
    ('pm', 'pm.task', 'assignee', 'pm.task.update'),
    ('pm', 'pm.task', 'assignee', 'pm.task.read'),
    ('pm', 'pm.project', 'creator', 'pm.project.update'),
    ('pm', 'pm.project', 'creator', 'pm.project.delete'),
    ('hrm', 'hrm.leave_request', 'creator', 'hrm.leave_request.update'),
    ('hrm', 'hrm.leave_request', 'creator', 'hrm.leave_request.delete'),
    ('hrm', 'hrm.leave_request', 'approver', 'hrm.leave_request.approve'),
    ('scm', 'scm.purchase_order', 'creator', 'scm.purchase_order.update'),
    ('scm', 'scm.purchase_order', 'approver', 'scm.purchase_order.approve'),
    ('scm', 'scm.purchase_requisition', 'creator', 'scm.purchase_requisition.update'),
    ('scm', 'scm.purchase_requisition', 'approver', 'scm.purchase_requisition.approve'),
    ('clm', 'clm.contract', 'creator', 'clm.contract.update'),
    ('clm', 'clm.contract', 'approver', 'clm.contract.approve'),
]


class Command(BaseCommand):
    help = 'Seed default roles and permissions for the Nexa platform'

    def add_arguments(self, parser):
        parser.add_argument(
            '--reset',
            action='store_true',
            help='Delete existing permissions and roles before seeding',
        )
        parser.add_argument(
            '--tenant-id',
            type=int,
            default=None,
            help='Tenant ID for roles (defaults to first tenant)',
        )

    @transaction.atomic
    def handle(self, *args, **options):
        # Resolve tenant for role creation
        from apps.core.tenant.models import Tenant
        tenant_id = options.get('tenant_id')
        if tenant_id:
            try:
                tenant = Tenant.objects.get(pk=tenant_id)
            except Tenant.DoesNotExist:
                self.stderr.write(self.style.ERROR(f'Tenant with id={tenant_id} not found'))
                return
        else:
            tenant = Tenant.objects.first()
            if not tenant:
                self.stderr.write(self.style.ERROR('No tenants found. Create a tenant first.'))
                return

        self.stdout.write(f'Using tenant: {tenant.name} (id={tenant.pk})')

        if options['reset']:
            self.stdout.write(self.style.WARNING('Resetting permissions and roles...'))
            RAICPolicy.objects.all().delete()
            RolePermission.objects.all().delete()
            Permission.objects.all().delete()
            Role.all_tenants.filter(is_system=True).delete()

        # 1. Create permissions
        all_perm_defs = list(PLATFORM_PERMISSIONS)
        for module_perms in MODULE_PERMISSIONS.values():
            all_perm_defs.extend(module_perms)

        perm_count = 0
        perm_map = {}  # codename → Permission instance
        for module, resource, action, name, is_sensitive in all_perm_defs:
            codename = f'{module}.{resource}.{action}'
            perm, created = Permission.objects.update_or_create(
                codename=codename,
                defaults={
                    'name': name,
                    'module': module,
                    'resource': resource,
                    'action': action,
                    'is_sensitive': is_sensitive,
                },
            )
            perm_map[codename] = perm
            if created:
                perm_count += 1

        self.stdout.write(self.style.SUCCESS(
            f'✓ {perm_count} permissions created ({len(perm_map)} total)'
        ))

        # 2. Create roles & assign permissions
        all_codenames = set(perm_map.keys())
        role_count = 0

        for slug, role_def in ROLES.items():
            role, created = Role.all_tenants.get_or_create(
                slug=slug,
                tenant=tenant,
                defaults={
                    'name': role_def['name'],
                    'description': role_def['description'],
                    'is_system': role_def['is_system'],
                },
            )
            if created:
                role_count += 1

            # Resolve permissions for this role
            perm_patterns = role_def['permissions']
            if perm_patterns == '__all__':
                role_perms = set(all_codenames)
            else:
                role_perms = set()
                for pattern in perm_patterns:
                    role_perms.update(_resolve_pattern(pattern, all_codenames))

            # Assign permissions
            assigned = 0
            for codename in sorted(role_perms):
                if codename in perm_map:
                    _, rp_created = RolePermission.objects.get_or_create(
                        role=role,
                        permission=perm_map[codename],
                    )
                    if rp_created:
                        assigned += 1

            self.stdout.write(
                f'  → نقش «{role.name}» ({slug}): {assigned} دسترسی جدید تخصیص شد'
            )

        self.stdout.write(self.style.SUCCESS(
            f'✓ {role_count} roles created'
        ))

        # 3. Create RAIC policies
        raic_count = 0
        for module, obj_type, rel_type, perm_codename in RAIC_DEFAULTS:
            perm = perm_map.get(perm_codename)
            if not perm:
                self.stdout.write(self.style.WARNING(
                    f'  ⚠ Permission {perm_codename} not found for RAIC policy'
                ))
                continue
            _, created = RAICPolicy.objects.get_or_create(
                module=module,
                object_type=obj_type,
                relation_type=rel_type,
                permission=perm,
                defaults={'is_active': True},
            )
            if created:
                raic_count += 1

        self.stdout.write(self.style.SUCCESS(
            f'✓ {raic_count} RAIC policies created'
        ))

        self.stdout.write(self.style.SUCCESS('\n✅ Seed complete!'))


def _resolve_pattern(pattern: str, all_codenames: set[str]) -> set[str]:
    """
    Resolve a permission pattern to matching codenames.

    Supported patterns:
    - 'platform.user.create'        → exact match
    - 'platform.user.*'             → all actions for resource
    - '*.*.read'                    → all read permissions
    - 'pm.*'                        → all PM module permissions
    - 'platform.*'                  → all platform permissions
    """
    parts = pattern.split('.')
    matched = set()

    for codename in all_codenames:
        code_parts = codename.split('.')

        # Handle 2-part patterns like 'platform.*' or 'hrm.*'
        if len(parts) == 2:
            if parts[0] == '*' or parts[0] == code_parts[0]:
                if parts[1] == '*' or (len(code_parts) > 1 and parts[1] == code_parts[1]):
                    matched.add(codename)
            continue

        # Handle 3-part patterns like '*.*.read' or 'platform.user.create'
        if len(code_parts) < len(parts):
            continue

        match = True
        for i, part in enumerate(parts):
            if part == '*':
                continue
            if i >= len(code_parts) or code_parts[i] != part:
                match = False
                break

        if match:
            matched.add(codename)

    return matched
