import os
import shutil
import re

def to_delphi_string(s):
    res = []
    in_quote = False
    for ch in s:
        code = ord(ch)
        if code > 127:
            if in_quote:
                res.append("'")
                in_quote = False
            res.append(f'#{code}')
        elif ch == "'":
            if in_quote:
                res.append("''")
            else:
                res.append("''''")
        else:
            if not in_quote:
                res.append("'")
                in_quote = True
            res.append(ch)
    if in_quote:
        res.append("'")
    return ''.join(res)

def format_png_to_dfm_data(png_path):
    with open(png_path, 'rb') as f:
        b = f.read()
    hex_str = b.hex().upper()
    lines = []
    for i in range(0, len(hex_str), 66):
        lines.append('              ' + hex_str[i:i+66])
    return '\n'.join(lines)

# Backup files first
shutil.copyfile('src/Data/dmg_Main.dfm', 'src/Data/dmg_Main.dfm.bak')
shutil.copyfile('src/UI/frm_Main.dfm', 'src/UI/frm_Main.dfm.bak')

with open('src/Data/dmg_Main.dfm', 'r', encoding='latin-1') as f:
    dmg_dfm = f.read()

# Icons to inject if not in imgCollection
icons_to_inject = [
    'icon_asistente_ia', 'icon_empresa_corp', 'icon_series_facturacion',
    'Gestión de IVA', 'Gestión de Proveedores', 'Desempeño', 'Nómina',
    'Integración', 'Recepción', 'Programación'
]

# Find imgCollection end
col_start = dmg_dfm.find('object imgCollection: TImageCollection')
ribbon_start = dmg_dfm.find('object imgListRibbon: TVirtualImageList')

col_block = dmg_dfm[col_start:ribbon_start]
ribbon_block = dmg_dfm[ribbon_start:]

# Inject missing into imgCollection
col_items_to_add = []
ribbon_items_to_add = []

for icon_name in icons_to_inject:
    png_file = os.path.join('resources/iconos_secciones', icon_name + '.png')
    if not os.path.exists(png_file):
        print(f'Warning: {png_file} does not exist!')
        continue
    
    delphi_name = to_delphi_string(icon_name)
    
    # Check if already in collection
    if f"Name = {delphi_name}" not in col_block:
        hex_data = format_png_to_dfm_data(png_file)
        item_text = f"""      item
        Name = {delphi_name}
        SourceImages = <
          item
            Image.Data = {{
{hex_data}
            }}
          end>
      end"""
        col_items_to_add.append(item_text)
        print(f'Adding {icon_name} to imgCollection')
        
    # Check if already in ribbon
    if f"CollectionName = {delphi_name}" not in ribbon_block:
        rib_text = f"""      item
        CollectionName = {delphi_name}
        Name = {delphi_name}
      end"""
        ribbon_items_to_add.append(rib_text)
        print(f'Adding {icon_name} to imgListRibbon')

# Insert before end of imgCollection (which ends with '    Left = 120')
# In dmg_Main.dfm:
#           end>
#       end>
#     Left = 120
#     Top = 264
#   end
#   object imgListRibbon: TVirtualImageList

if col_items_to_add:
    # Find the closing '    Left = ' of imgCollection
    search_marker = '\n    Left = 120\n    Top = 264\n  end\n  object imgListRibbon:'
    marker_pos = dmg_dfm.find(search_marker)
    if marker_pos != -1:
        addition = '\n' + '\n'.join(col_items_to_add)
        dmg_dfm = dmg_dfm[:marker_pos] + addition + dmg_dfm[marker_pos:]
        print('Successfully injected into imgCollection')
    else:
        print('ERROR: search_marker for imgCollection not found!')

if ribbon_items_to_add:
    # Find end of imgListRibbon items list:
    #         CollectionName = 'icon_config_email'
    #         Name = 'icon_config_email'
    #       end>
    #     ImageCollection = imgCollection
    search_marker2 = '\n    ImageCollection = imgCollection'
    marker_pos2 = dmg_dfm.find(search_marker2)
    if marker_pos2 != -1:
        addition2 = '\n' + '\n'.join(ribbon_items_to_add)
        dmg_dfm = dmg_dfm[:marker_pos2] + addition2 + dmg_dfm[marker_pos2:]
        print('Successfully injected into imgListRibbon')
    else:
        print('ERROR: search_marker2 for imgListRibbon not found!')

with open('src/Data/dmg_Main.dfm', 'w', encoding='latin-1') as f:
    f.write(dmg_dfm)

print('dmg_Main.dfm updated.')

# Now update frm_Main.dfm
BUTTON_MAP = {
    'btnChatIA': 'icon_asistente_ia',
    'btnEmpresasRibbon': 'icon_empresa_corp',
    'btnSeries': 'icon_series_facturacion',
    'btnConfigConexion': 'Seguridad',
    'btnTiposIva': 'Gestión de IVA',
    'btnFormasPago': 'Pagos',
    'btnCambiarEmpresa': 'icon_empresa_corp',
    'btnEventos': 'Actividad',
    'btnArticulos': 'Stock',
    'btnEventosMaterialesCat': 'Lista de Materiales (LdM)',
    'btnProveedor': 'Gestión de Proveedores',
    'btnArticulosProv': 'Abastecimiento',
    'btnEntradasMateriasPrimas': 'Recepción',
    'btnProvPreciosVariaciones': 'Comparativa de Ofertas',
    'btnCalendarioProduccion': 'Calendario',
    'btnLotesRibbon': 'Movimiento de Stock',
    'btnMateriasPrimas': 'Lista de Materiales (LdM)',
    'btnRecetas': 'Programación',
    'btnAlmacenes': 'Almacenamiento',
    'btnObradores': 'Orden de Trabajo',
    'btnFamilias': 'Ubicaciones',
    'btnAlergenos': 'alergenos',
    'btnAsignarMateriasPrimas': 'asignacion_materias_primas',
    'btnInventariosRibbon': 'Niveles de Inventario',
    'btnIncidencias': 'Reparaciones',
    'btnFormatosPresentacion': 'Adquisiciones',
    'btnFormatosEnvio': 'Albaranes de Entrega',
    'btnStockEnvasado': 'Stock',
    'btnCalidadDocumentos': 'Control de Calidad',
    'btnCalidadRegistros': 'Certificados de Origen',
    'btnCalidadPrerrequisitos': 'Registros de Mantenimiento',
    'btnCalidadIncidencias': 'Registros de Auditoria',
    'btnCalidadVerificacion': 'Control de Calidad',
    'btnCalidadTrazabilidad': 'Certificados de Origen',
    'btnCalidadGruposControl': 'Pruebas',
    'btnCalidadHitos': 'Registros de Auditoria',
    'btnPrepararPedidos': 'Albaranes de Entrega',
    'btnTrabajadoresRibbon': 'Registros de Empleados',
    'btnFichajesRibbon': 'Hojas de Tiempo',
    'btnTiemposAreasRibbon': 'Desempeño',
    'btnCostesManoObraRibbon': 'Nómina',
    'btnTerminalPlantaRibbon': 'Actividad',
    'btnImportarfactusol': 'Integración',
    'btnReportTemplates': 'Informes',
    'btnTermometroBLE': 'API',
}

with open('src/UI/frm_Main.dfm', 'r', encoding='latin-1') as f:
    frm_dfm = f.read()

for btn_name, target_icon in BUTTON_MAP.items():
    delphi_target = to_delphi_string(target_icon)
    
    # Pattern to match the button object block
    btn_pattern = rf'(object {btn_name}: TSpeedButton.*?)(end\b)'
    match = re.search(btn_pattern, frm_dfm, re.DOTALL)
    if not match:
        print(f'Warning: button {btn_name} not found in frm_Main.dfm')
        continue
    
    body = match.group(1)
    
    # Replace or add ImageName
    if 'ImageName =' in body:
        new_body = re.sub(r'ImageName = [^\r\n]+', f'ImageName = {delphi_target}', body)
    else:
        # insert ImageName before Images =
        new_body = body.replace('Images = dmgMain.imgListRibbon', f'ImageName = {delphi_target}\n          Images = dmgMain.imgListRibbon')
    
    # Also ensure ImageIndex is removed or set to -1 so Delphi always binds by ImageName
    new_body = re.sub(r'ImageIndex = \d+\r?\n\s*', '', new_body)
    
    frm_dfm = frm_dfm[:match.start()] + new_body + match.group(2) + frm_dfm[match.end():]
    print(f'Updated {btn_name} -> ImageName = {delphi_target}')

with open('src/UI/frm_Main.dfm', 'w', encoding='latin-1') as f:
    f.write(frm_dfm)

print('frm_Main.dfm successfully updated!')
