#!/usr/bin/env python3
"""
migrate_fa_to_lucide.py — Replace FontAwesome <span class="fas fa-X"> with Lucide components.

Usage:
  python3 scripts/migrate_fa_to_lucide.py src/routes/events/[event_id]/\(pres_mgmt\)/

Skips content inside HTML comments. Adds/merges lucide-svelte imports.
"""
import re
import sys
import os
from pathlib import Path

# ── FA icon → Lucide component name ─────────────────────────────────────────
FA_TO_LUCIDE = {
    'fa-spinner':            'LoaderCircle',
    'fa-cog':                'LoaderCircle',    # only when fa-spin
    'fa-sync-alt':           'RefreshCw',
    'fa-times':              'X',
    'fa-exclamation-triangle': 'TriangleAlert',
    'fa-check':              'Check',
    'fa-check-circle':       'CircleCheck',
    'fa-plus':               'Plus',
    'fa-minus':              'Minus',
    'fa-save':               'Save',
    'fa-edit':               'Pencil',
    'fa-eye':                'Eye',
    'fa-eye-slash':          'EyeOff',
    'fa-toggle-on':          'ToggleRight',
    'fa-toggle-off':         'ToggleLeft',
    'fa-star-of-life':       'Asterisk',
    'fa-id-card':            'IdCard',
    'fa-paper-plane':        'Send',
    'fa-map-marker-alt':     'MapPin',
    'fa-file-alt':           'FileText',
    'fa-envelope':           'Mail',
    'fa-book':               'BookOpen',
    'fa-angle-right':        'ChevronRight',
    'fa-user':               'User',
    'fa-tasks':              'ListChecks',
    'fa-plane':              'Plane',
    'fa-list':               'List',
    'fa-link':               'Link',
    'fa-file-archive':       'Archive',
    'fa-comment-dots':       'MessageCircle',
    'fa-chevron-up':         'ChevronUp',
    'fa-chevron-down':       'ChevronDown',
    'fa-camera':             'Camera',
    'fa-barcode':            'Barcode',
    'fa-upload':             'Upload',
    'fa-search':             'Search',
    'fa-mail-bulk':          'Mails',
    'fa-laptop-code':        'Laptop',
    'fa-copy':               'Copy',
    'fa-user-tag':           'Tag',
    'fa-user-secret':        'UserRound',
    'fa-users':              'Users',
    'fa-user-circle':        'CircleUser',
    'fa-sort':               'ArrowUpDown',
    'fa-question':           'HelpCircle',
    'fa-map-marked':         'MapPinned',
    'fa-list-ol':            'ListOrdered',
    'fa-laptop':             'Laptop',
    'fa-info':               'Info',
    'fa-building':           'Building2',
    'fa-user-slash':         'UserX',
    'fa-user-check':         'UserCheck',
    'fa-unlink':             'Unlink',
    'fa-star':               'Star',
    'fa-search-location':    'MapPin',
    'fa-remove-format':      'RemoveFormatting',
    'fa-qrcode':             'QrCode',
    'fa-key':                'Key',
    'fa-heartbeat':          'HeartPulse',
    'fa-hat-wizard':         'Wand2',
    'fa-fingerprint':        'Fingerprint',
    'fa-file-csv':           'FileSpreadsheet',
    'fa-file':               'File',
    'fa-clock':              'Clock',
    'fa-clipboard-list':     'ClipboardList',
    'fa-chart-line':         'TrendingUp',
    'fa-chalkboard-teacher': 'Presentation',
    'fa-calendar-day':       'CalendarDays',
    'fa-bell-slash':         'BellOff',
    'fa-bell':               'Bell',
    # ── Additional mappings ──────────────────────────────────────────────────
    'fa-arrow-left':         'ArrowLeft',
    'fa-arrow-right':        'ArrowRight',
    'fa-arrow-up':           'ArrowUp',
    'fa-arrow-down':         'ArrowDown',
    'fa-ban':                'Ban',
    'fa-broom':              'Trash2',       # closest semantic match
    'fa-calendar-alt':       'CalendarDays',
    'fa-database':           'Database',
    'fa-door-open':          'DoorOpen',
    'fa-download':           'Download',
    'fa-exchange-alt':       'ArrowLeftRight',
    'fa-file-image':         'FileImage',
    'fa-lock':               'Lock',
    'fa-magic':              'Sparkles',
    'fa-print':              'Printer',
    'fa-sticky-note':        'StickyNote',
    'fa-sync':               'RefreshCw',
    'fa-tag':                'Tag',
    'fa-trash':              'Trash2',
    'fa-user-ninja':         'UserRound',
    'fa-user-tie':           'UserRound',
    'fa-video':              'Video',
    'fa-archive':            'Archive',
    'fa-link-slash':         'Unlink',
    'fa-question-circle':    'HelpCircle',
    # ── Additional unmapped icons ──────────────────────────────────────────────
    'fa-compress-arrows-alt':'Minimize2',
    'fa-expand-arrows-alt':  'Maximize2',
    'fa-secret':             'ShieldCheck',
    'fa-user-shield':        'ShieldUser',
    'fa-user-nurse':         'UserRound',
    'fa-user-friends':       'Users',
    'fa-user-plus':          'UserPlus',
    'fa-user-edit':          'UserRoundPen',
    'fa-palette':            'Palette',
    'fa-eraser':             'Eraser',
    'fa-code':               'Code',
    'fa-lock-open':          'LockOpen',
    'fa-unlock':             'LockOpen',
    'fa-trash-alt':          'Trash2',
    'fa-folder-open':        'FolderOpen',
    'fa-minus-circle':       'MinusCircle',
    'fa-plus-circle':        'PlusCircle',
    'fa-window-close':       'X',
    'fa-cut':                'Scissors',
    'fa-caret-down':         'ChevronDown',
    'fa-caret-right':        'ChevronRight',
    'fa-cogs':               'Settings2',
    'fa-phone':              'Phone',
    'fa-phone-slash':        'PhoneOff',
    'fa-flag':               'Flag',
    'fa-calendar-week':      'CalendarDays',
    'fa-address-book':       'BookUser',
    'fa-info-circle':        'Info',
    'fa-comment-slash':      'MessageX',
    'fa-paperclip':          'Paperclip',
    'fa-keyboard':           'Keyboard',
    'fa-crosshairs':         'Crosshair',
    'fa-redo':               'RotateCcw',
    'fa-tools':              'Wrench',
    'fa-video-slash':        'VideoOff',
    'fa-home':               'House',
    'fa-calendar':           'Calendar',
    'fa-check-square':       'SquareCheck',
    'fa-square':             'Square',
    'fa-times-circle':       'CircleX',
    'fa-undo':               'RotateCcw',
    'fa-trash-restore':      'ArchiveRestore',
    'fa-lock-open':          'LockOpen',
    'fa-compress':           'Minimize2',
    'fa-expand':             'Maximize2',
    'fa-grip-lines':         'GripHorizontal',
    'fa-bars':               'Menu',
    'fa-refresh':            'RefreshCw',
}

# Skip modifiers — not real icon names
FA_MODIFIERS = {'fas', 'far', 'fab', 'fa-spin', 'fa-fw', 'fa-lg', 'fa-2x', 'fa-sm'}

# ── Pattern: <span class="fas fa-X [extras]" [other-attrs]></span> ───────────
# [^>]* matches newlines too (character class, not dot)
SPAN_RE = re.compile(
    r'<span\s+class="((?:fas|far|fab)\s+fa-[^"]*)"[^>]*>\s*</span>'
)

# ── Comment splitter ─────────────────────────────────────────────────────────
COMMENT_RE = re.compile(r'(<!--[\s\S]*?-->)')

# ── Lucide import line ────────────────────────────────────────────────────────
IMPORT_RE = re.compile(r"import\s*\{([^}]+)\}\s*from\s*'@lucide/svelte'\s*;?")


def parse_fa_class(class_str):
    """Return (icon_name, extra_classes, has_spin) from a FA class string."""
    parts = class_str.split()
    icon_name = None
    has_spin = 'fa-spin' in parts
    extra = []
    for p in parts:
        if p in FA_MODIFIERS:
            continue
        elif p.startswith('fa-'):
            if icon_name is None:
                icon_name = p  # first real icon name wins
            extra.append(p)
    return icon_name, extra, has_spin


def replace_span(m):
    """Regex sub callback: replace a single FA span with a Lucide component."""
        """
    if icon_name is None:
        return m.group(0)

    lucide = FA_TO_LUCIDE.get(icon_name)
    if lucide is None:
        print(f'  ⚠  no mapping for {icon_name!r} — left as-is', file=sys.stderr)
        return m.group(0)

    classes = extra[:]
    if has_spin:
        classes.append('animate-spin')

    class_attr = f' class="{" ".join(classes)}"' if classes else ''
    return f'<{lucide} size="1em"{class_attr} />'


def process_content(content):
    """Replace FA spans, skip HTML comments. Return (new_content, used_icons)."""
    used_icons = set()

    def track_and_replace(m):
        result = replace_span(m)
        if result != m.group(0):
            # Extract lucide name from result
            lucide_name = result.split()[0].lstrip('<')
            used_icons.add(lucide_name)
        return result

    # Split by comments; only process non-comment segments
    parts = COMMENT_RE.split(content)
    new_parts = []
    for part in parts:
        if part.startswith('<!--'):
            new_parts.append(part)
        else:
            new_parts.append(SPAN_RE.sub(track_and_replace, part))

    return ''.join(new_parts), used_icons


def add_import(content, icons):
    """Add/merge lucide-svelte import line inside <script>."""
    if not icons:
        return content

    sorted_icons = sorted(icons)

    existing = IMPORT_RE.search(content)
    if existing:
        current = [s.strip() for s in existing.group(1).split(',') if s.strip()]
        merged = sorted(set(current) | set(sorted_icons))
        new_import = f"import {{ {', '.join(merged)} }} from '@lucide/svelte';"
        return content[:existing.start()] + new_import + content[existing.end():]
    else:
        # Insert after the last COMPLETE import statement (handles multiline imports).
        # A complete import statement ends with: } from '...'; or import '...';
        complete_import_re = re.compile(
            r'^[ \t]*import\b[\s\S]*?(?:from\s*[\'"][^\'"]+[\'"]|[\'"][^\'"]+[\'"])\s*;?',
            re.MULTILINE
        )
        all_imports = list(complete_import_re.finditer(content))
        if all_imports:
            pos = all_imports[-1].end()
            new_line = f"\n    import {{ {', '.join(sorted_icons)} }} from '@lucide/svelte';"
            return content[:pos] + new_line + content[pos:]
        # Fallback: add after <script> tag
        script_tag = content.find('<script')
        if script_tag != -1:
            end = content.index('>', script_tag) + 1
            return content[:end] + f"\n    import {{ {', '.join(sorted_icons)} }} from 'lucide-svelte';" + content[end:]
        return content


def migrate_file(filepath):
    path = Path(filepath)
    original = path.read_text()
    new_content, used_icons = process_content(original)

    if used_icons:
        new_content = add_import(new_content, used_icons)

    if new_content != original:
        path.write_text(new_content)
        print(f'  ✓  {path.name}  ({len(used_icons)} icon types: {", ".join(sorted(used_icons))})')
        return True
    else:
        print(f'  –  {path.name}  (no changes)')
        return False


def main():
    if len(sys.argv) < 2:
        print('Usage: migrate_fa_to_lucide.py <directory_or_file ...>')
        sys.exit(1)


    # IDAA Guardrail: Abort if any target is src/routes/idaa or a subdirectory
    for arg in sys.argv[1:]:
        if Path(arg).resolve().as_posix().endswith('src/routes/idaa') or '/src/routes/idaa/' in Path(arg).resolve().as_posix():
            print('ABORT: This script must not be run against src/routes/idaa or its subdirectories. IDAA content is private and protected.')
            sys.exit(1)

    targets = []
    for arg in sys.argv[1:]:
        p = Path(arg)
        if p.is_dir():
            targets.extend(sorted(p.rglob('*.svelte')))
        elif p.is_file():
            targets.append(p)
        else:
            print(f'Not found: {arg}', file=sys.stderr)

    changed = 0
    for t in targets:
        if migrate_file(t):
            changed += 1

    print(f'\n{changed}/{len(targets)} files modified.')


if __name__ == '__main__':
    main()
