import os
import shutil
import re

NEW_ICONS = [
    # Producción (14)
    "icon_prod_calendario",
    "icon_prod_obradores",
    "icon_prod_almacenes",
    "icon_prod_familias",
    "icon_prod_materias_primas",
    "icon_prod_recetas",
    "icon_prod_lotes",
    "icon_prod_alergenos",
    "icon_prod_asignar_mp",
    "icon_prod_inventarios",
    "icon_prod_incidencias",
    "icon_prod_formatos_presentacion",
    "icon_prod_formatos_envio",
    "icon_prod_stock_envasado",
    # Empresa (6)
    "icon_emp_empresas",
    "icon_emp_selec_emp",
    "icon_emp_series",
    "icon_emp_tipos_iva",
    "icon_emp_config",
    "icon_emp_formas_pago"
]

BUTTON_MAPPING = {
    # Empresa
    "btnEmpresasRibbon": "icon_emp_empresas",
    "btnCambiarEmpresa": "icon_emp_selec_emp",
    "btnSeries": "icon_emp_series",
    "btnConfigConexion": "icon_emp_config",
    "btnTiposIva": "icon_emp_tipos_iva",
    "btnFormasPago": "icon_emp_formas_pago",
    # Producción
    "btnCalendarioProduccion": "icon_prod_calendario",
    "btnObradores": "icon_prod_obradores",
    "btnAlmacenes": "icon_prod_almacenes",
    "btnFamilias": "icon_prod_familias",
    "btnMateriasPrimas": "icon_prod_materias_primas",
    "btnRecetas": "icon_prod_recetas",
    "btnLotesRibbon": "icon_prod_lotes",
    "btnAlergenos": "icon_prod_alergenos",
    "btnAsignarMateriasPrimas": "icon_prod_asignar_mp",
    "btnInventariosRibbon": "icon_prod_inventarios",
    "btnIncidencias": "icon_prod_incidencias",
    "btnFormatosPresentacion": "icon_prod_formatos_presentacion",
    "btnFormatosEnvio": "icon_prod_formatos_envio",
    "btnStockEnvasado": "icon_prod_stock_envasado"
}

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)

# 1. Backups
shutil.copyfile("src/Data/dmg_Main.dfm", "src/Data/dmg_Main.dfm.bak2")
shutil.copyfile("src/UI/frm_Main.dfm", "src/UI/frm_Main.dfm.bak2")

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

col_marker = "\n    Left = 120\n    Top = 264\n  end\n  object imgListRibbon: TVirtualImageList"
rib_marker = "\n    ImageCollection = imgCollection\n    Width = 32\n    Height = 32"

col_pos = dmg_dfm.find(col_marker)
rib_pos = dmg_dfm.find(rib_marker)

if col_pos == -1 or rib_pos == -1:
    raise Exception(f"Markers not found: col_pos={col_pos}, rib_pos={rib_pos}")

col_block = dmg_dfm[:col_pos]
rib_block = dmg_dfm[col_pos:rib_pos]

col_additions = []
rib_additions = []

for icon_name in NEW_ICONS:
    png_path = os.path.join("resources/iconos_secciones", f"{icon_name}.png")
    if not os.path.exists(png_path):
        raise Exception(f"File not found: {png_path}")
    
    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_path)
        col_item = f"""      item
        Name = {delphi_name}
        SourceImages = <
          item
            Image.Data = {{
{hex_data}
            }}
          end>
      end"""
        col_additions.append(col_item)
        print(f"Adding to imgCollection: {icon_name}")
    else:
        print(f"Already in imgCollection: {icon_name}")

    # Check if already in ribbon
    if f"CollectionName = {delphi_name}" not in rib_block:
        rib_item = f"""      item
        CollectionName = {delphi_name}
        Name = {delphi_name}
      end"""
        rib_additions.append(rib_item)
        print(f"Adding to imgListRibbon: {icon_name}")
    else:
        print(f"Already in imgListRibbon: {icon_name}")

if col_additions:
    dmg_dfm = dmg_dfm[:col_pos] + "\n" + "\n".join(col_additions) + dmg_dfm[col_pos:]
    # recompute rib_pos
    rib_pos = dmg_dfm.find(rib_marker)

if rib_additions:
    dmg_dfm = dmg_dfm[:rib_pos] + "\n" + "\n".join(rib_additions) + dmg_dfm[rib_pos:]

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

print("dmg_Main.dfm updated successfully!")

# Parse all items in updated imgListRibbon to determine exact indices
with open("src/Data/dmg_Main.dfm", "r", encoding="latin-1") as f:
    dmg_updated = f.read()

rib_start = dmg_updated.find("object imgListRibbon: TVirtualImageList")
rib_end = dmg_updated.find(rib_marker, rib_start)
rib_section = dmg_updated[rib_start:rib_end]

# Extract names in order
item_names = re.findall(r"CollectionName = \'([^\']+)\'", rib_section)
name_to_index = {name: idx for idx, name in enumerate(item_names)}

print(f"imgListRibbon now has {len(item_names)} items.")

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

for btn_name, icon_name in BUTTON_MAPPING.items():
    delphi_icon = to_delphi_string(icon_name)
    idx = name_to_index.get(icon_name, -1)
    if idx == -1:
        print(f"Warning: {icon_name} not found in name_to_index!")
        continue
    
    btn_pattern = rf"(object {btn_name}: TSpeedButton.*?)(end\b)"
    match = re.search(btn_pattern, frm_dfm, re.DOTALL)
    if not match:
        print(f"Warning: {btn_name} not found in frm_Main.dfm")
        continue
    
    body = match.group(1)
    
    # Remove existing ImageIndex and ImageName
    body = re.sub(r"\s*ImageIndex\s*=\s*-?\d+\r?\n", "\n", body)
    body = re.sub(r"\s*ImageName\s*=\s*[^\r\n]+\r?\n", "\n", body)
    
    # Insert both ImageIndex and ImageName before Images = dmgMain.imgListRibbon
    insertion = f"\n          ImageIndex = {idx}\n          ImageName = {delphi_icon}"
    body = body.replace("Images = dmgMain.imgListRibbon", f"Images = dmgMain.imgListRibbon{insertion}")
    
    frm_dfm = frm_dfm[:match.start()] + body + match.group(2) + frm_dfm[match.end():]
    print(f"Updated {btn_name}: ImageName={icon_name}, ImageIndex={idx}")

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

print("frm_Main.dfm successfully updated with exact ImageIndex and ImageName!")
