/* Flota Web - versión directa para Cloudflare Pages.
   Presentación sin build: React se carga desde CDN y los datos desde GitHub. */
const { useCallback, useEffect, useMemo, useState } = React;
const vehicleIndex = {
  "1161": [
    {
      "variant": "A",
      "src": "/assets/vehicles/1161/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/1161/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/1161/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/1161/d.webp"
    }
  ],
  "1167": [
    {
      "variant": "A",
      "src": "/assets/vehicles/1167/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/1167/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/1167/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/1167/d.webp"
    }
  ],
  "1168": [
    {
      "variant": "A",
      "src": "/assets/vehicles/1168/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/1168/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/1168/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/1168/d.webp"
    }
  ],
  "1170": [
    {
      "variant": "A",
      "src": "/assets/vehicles/1170/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/1170/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/1170/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/1170/d.webp"
    }
  ],
  "1171": [
    {
      "variant": "A",
      "src": "/assets/vehicles/1171/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/1171/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/1171/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/1171/d.webp"
    }
  ],
  "1183": [
    {
      "variant": "A",
      "src": "/assets/vehicles/1183/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/1183/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/1183/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/1183/d.webp"
    }
  ],
  "1189": [
    {
      "variant": "A",
      "src": "/assets/vehicles/1189/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/1189/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/1189/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/1189/d.webp"
    }
  ],
  "1204": [
    {
      "variant": "A",
      "src": "/assets/vehicles/1204/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/1204/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/1204/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/1204/d.webp"
    }
  ],
  "1210": [
    {
      "variant": "A",
      "src": "/assets/vehicles/1210/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/1210/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/1210/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/1210/d.webp"
    }
  ],
  "1212": [
    {
      "variant": "A",
      "src": "/assets/vehicles/1212/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/1212/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/1212/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/1212/d.webp"
    }
  ],
  "1214": [
    {
      "variant": "A",
      "src": "/assets/vehicles/1214/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/1214/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/1214/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/1214/d.webp"
    }
  ],
  "1215": [
    {
      "variant": "A",
      "src": "/assets/vehicles/1215/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/1215/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/1215/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/1215/d.webp"
    }
  ],
  "1217": [
    {
      "variant": "A",
      "src": "/assets/vehicles/1217/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/1217/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/1217/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/1217/d.webp"
    }
  ],
  "1218": [
    {
      "variant": "A",
      "src": "/assets/vehicles/1218/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/1218/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/1218/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/1218/d.webp"
    }
  ],
  "1219": [
    {
      "variant": "A",
      "src": "/assets/vehicles/1219/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/1219/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/1219/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/1219/d.webp"
    }
  ],
  "1321": [
    {
      "variant": "A",
      "src": "/assets/vehicles/1321/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/1321/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/1321/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/1321/d.webp"
    }
  ],
  "2019": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2019/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2019/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2019/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2019/d.webp"
    }
  ],
  "2069": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2069/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2069/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2069/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2069/d.webp"
    }
  ],
  "2082": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2082/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2082/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2082/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2082/d.webp"
    }
  ],
  "2101": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2101/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2101/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2101/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2101/d.webp"
    }
  ],
  "2103": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2103/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2103/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2103/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2103/d.webp"
    }
  ],
  "2104": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2104/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2104/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2104/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2104/d.webp"
    }
  ],
  "2106": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2106/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2106/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2106/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2106/d.webp"
    }
  ],
  "2107": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2107/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2107/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2107/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2107/d.webp"
    }
  ],
  "2109": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2109/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2109/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2109/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2109/d.webp"
    }
  ],
  "2110": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2110/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2110/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2110/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2110/d.webp"
    }
  ],
  "2114": [
    {
      "variant": "B",
      "src": "/assets/vehicles/2114/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2114/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2114/d.webp"
    }
  ],
  "2117": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2117/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2117/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2117/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2117/d.webp"
    }
  ],
  "2118": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2118/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2118/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2118/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2118/d.webp"
    }
  ],
  "2122": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2122/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2122/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2122/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2122/d.webp"
    }
  ],
  "2126": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2126/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2126/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2126/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2126/d.webp"
    }
  ],
  "2130": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2130/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2130/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2130/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2130/d.webp"
    }
  ],
  "2131": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2131/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2131/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2131/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2131/d.webp"
    }
  ],
  "2132": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2132/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2132/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2132/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2132/d.webp"
    }
  ],
  "2138": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2138/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2138/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2138/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2138/d.webp"
    }
  ],
  "2139": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2139/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2139/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2139/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2139/d.webp"
    }
  ],
  "2149": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2149/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2149/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2149/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2149/d.webp"
    }
  ],
  "2150": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2150/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2150/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2150/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2150/d.webp"
    }
  ],
  "2151": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2151/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2151/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2151/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2151/d.webp"
    }
  ],
  "2152": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2152/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2152/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2152/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2152/d.webp"
    }
  ],
  "26104": [
    {
      "variant": "A",
      "src": "/assets/vehicles/26104/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/26104/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/26104/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/26104/d.webp"
    }
  ],
  "2632": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2632/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2632/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2632/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2632/d.webp"
    }
  ],
  "2633": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2633/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2633/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2633/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2633/d.webp"
    }
  ],
  "2634": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2634/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2634/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2634/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2634/d.webp"
    }
  ],
  "2635": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2635/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2635/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2635/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2635/d.webp"
    }
  ],
  "2636": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2636/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2636/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2636/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2636/d.webp"
    }
  ],
  "2637": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2637/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2637/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2637/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2637/d.webp"
    }
  ],
  "2638": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2638/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2638/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2638/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2638/d.webp"
    }
  ],
  "2640": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2640/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2640/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2640/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2640/d.webp"
    }
  ],
  "2641": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2641/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2641/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2641/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2641/d.webp"
    }
  ],
  "2643": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2643/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2643/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2643/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2643/d.webp"
    }
  ],
  "2644": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2644/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2644/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2644/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2644/d.webp"
    }
  ],
  "2645": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2645/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2645/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2645/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2645/d.webp"
    }
  ],
  "2646": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2646/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2646/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2646/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2646/d.webp"
    }
  ],
  "2654": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2654/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2654/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2654/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2654/d.webp"
    }
  ],
  "2657": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2657/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2657/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2657/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2657/d.webp"
    }
  ],
  "2658": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2658/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2658/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2658/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2658/d.webp"
    }
  ],
  "2659": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2659/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2659/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2659/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2659/d.webp"
    }
  ],
  "2660": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2660/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2660/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2660/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2660/d.webp"
    }
  ],
  "2662": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2662/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2662/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2662/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2662/d.webp"
    }
  ],
  "2668": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2668/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2668/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2668/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2668/d.webp"
    }
  ],
  "2669": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2669/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2669/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2669/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2669/d.webp"
    }
  ],
  "2670": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2670/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2670/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2670/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2670/d.webp"
    }
  ],
  "2671": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2671/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2671/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2671/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2671/d.webp"
    }
  ],
  "2672": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2672/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2672/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2672/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2672/d.webp"
    }
  ],
  "2673": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2673/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2673/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2673/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2673/d.webp"
    }
  ],
  "2674": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2674/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2674/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2674/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2674/d.webp"
    }
  ],
  "2675": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2675/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2675/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2675/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2675/d.webp"
    }
  ],
  "2676": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2676/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2676/b.webp"
    },
    {
      "variant": "B2",
      "src": "/assets/vehicles/2676/b2.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2676/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2676/d.webp"
    }
  ],
  "2681": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2681/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2681/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2681/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2681/d.webp"
    }
  ],
  "2746": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2746/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2746/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2746/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2746/d.webp"
    }
  ],
  "2773": [
    {
      "variant": "A",
      "src": "/assets/vehicles/2773/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/2773/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/2773/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/2773/d.webp"
    }
  ],
  "3234": [
    {
      "variant": "A",
      "src": "/assets/vehicles/3234/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/3234/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/3234/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/3234/d.webp"
    }
  ],
  "3271": [
    {
      "variant": "A",
      "src": "/assets/vehicles/3271/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/3271/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/3271/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/3271/d.webp"
    }
  ],
  "3358": [
    {
      "variant": "A",
      "src": "/assets/vehicles/3358/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/3358/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/3358/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/3358/d.webp"
    }
  ],
  "346": [
    {
      "variant": "A",
      "src": "/assets/vehicles/346/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/346/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/346/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/346/d.webp"
    }
  ],
  "347": [
    {
      "variant": "A",
      "src": "/assets/vehicles/347/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/347/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/347/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/347/d.webp"
    }
  ],
  "3983": [
    {
      "variant": "A",
      "src": "/assets/vehicles/3983/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/3983/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/3983/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/3983/d.webp"
    }
  ],
  "3987": [
    {
      "variant": "A",
      "src": "/assets/vehicles/3987/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/3987/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/3987/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/3987/d.webp"
    }
  ],
  "8353": [
    {
      "variant": "A",
      "src": "/assets/vehicles/8353/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/8353/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/8353/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/8353/d.webp"
    }
  ],
  "8354": [
    {
      "variant": "A",
      "src": "/assets/vehicles/8354/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/8354/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/8354/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/8354/d.webp"
    }
  ],
  "8371": [
    {
      "variant": "A",
      "src": "/assets/vehicles/8371/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/8371/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/8371/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/8371/d.webp"
    }
  ],
  "9000": [
    {
      "variant": "A",
      "src": "/assets/vehicles/9000/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/9000/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/9000/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/9000/d.webp"
    }
  ],
  "9004": [
    {
      "variant": "A",
      "src": "/assets/vehicles/9004/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/9004/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/9004/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/9004/d.webp"
    }
  ],
  "9005": [
    {
      "variant": "A",
      "src": "/assets/vehicles/9005/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/9005/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/9005/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/9005/d.webp"
    }
  ],
  "9052": [
    {
      "variant": "A",
      "src": "/assets/vehicles/9052/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/9052/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/9052/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/9052/d.webp"
    }
  ],
  "9161": [
    {
      "variant": "A",
      "src": "/assets/vehicles/9161/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/9161/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/9161/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/9161/d.webp"
    }
  ],
  "9173": [
    {
      "variant": "A",
      "src": "/assets/vehicles/9173/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/9173/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/9173/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/9173/d.webp"
    }
  ],
  "9174": [
    {
      "variant": "A",
      "src": "/assets/vehicles/9174/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/9174/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/9174/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/9174/d.webp"
    }
  ],
  "930": [
    {
      "variant": "A",
      "src": "/assets/vehicles/930/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/930/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/930/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/930/d.webp"
    }
  ],
  "9319": [
    {
      "variant": "A",
      "src": "/assets/vehicles/9319/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/9319/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/9319/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/9319/d.webp"
    }
  ],
  "9351": [
    {
      "variant": "A",
      "src": "/assets/vehicles/9351/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/9351/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/9351/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/9351/d.webp"
    }
  ],
  "ALQ14": [
    {
      "variant": "A",
      "src": "/assets/vehicles/ALQ14/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/ALQ14/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/ALQ14/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/ALQ14/d.webp"
    }
  ],
  "PMA": [
    {
      "variant": "A",
      "src": "/assets/vehicles/PMA/a.webp"
    },
    {
      "variant": "B",
      "src": "/assets/vehicles/PMA/b.webp"
    },
    {
      "variant": "C",
      "src": "/assets/vehicles/PMA/c.webp"
    },
    {
      "variant": "D",
      "src": "/assets/vehicles/PMA/d.webp"
    }
  ]
};

function norm(value) {
  return String(value ?? '').trim();
}

function normalizeSearch(value) {
  return norm(value)
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
    .toLowerCase();
}

function uniqueValues(rows, column) {
  if (!column) return [];
  const map = new Map();
  for (const row of rows || []) {
    const raw = norm(row?.[column]);
    if (!raw) continue;
    const key = normalizeSearch(raw);
    if (!map.has(key)) map.set(key, raw);
  }
  return [...map.values()].sort((a, b) => a.localeCompare(b, 'es', { numeric: true }));
}

function getDependency(row = {}) {
  return norm(row['DEPENDENCIA ACTUAL']) || norm(row['DEP. ACTUAL']) || norm(row.DEPENDENCIA) || '-';
}

function recordTitle(row = {}, tabName = '') {
  return norm(row.UNIDAD) || norm(row.UTILIDAD) || norm(row['MARCA / MODELO']) || tabName || 'Unidad';
}

function statusClass(value) {
  const text = normalizeSearch(value).replace(/\s/g, '');
  if (['p/s','ps','servicio','enservicio','operativo','disponible'].includes(text)) return 'ok';
  if (['f/s','fs','fueradeservicio','baja','inoperativo'].includes(text)) return 'bad';
  if (!text) return 'neutral';
  return 'warn';
}

function compactDate(value) {
  const text = norm(value);
  if (!text || text === '-') return '-';
  const d = new Date(text);
  if (Number.isNaN(d.getTime())) return text;
  return new Intl.DateTimeFormat('es-AR', {
    dateStyle: 'short',
    timeStyle: 'short'
  }).format(d);
}

const GITHUB_OWNER = 'walter112358-boop';
const GITHUB_REPO = 'app_flota';
const GITHUB_BRANCH = 'main';

const DEFAULT_TABS = [
  {
    tab_id: 'grilla',
    nombre: 'Grilla',
    columnas: ['DEPENDENCIA','INTERNO','MARCA','MODELO','UTILIDAD','CARROZADO','BOMBA','DEPENDENCIA ACTUAL','ESTADO','OBSERVACIONES','TALLER'],
    tipo_base: 'Grilla'
  },
  {
    tab_id: 'carrozado',
    nombre: 'Carrozado',
    columnas: ['DEPENDENCIA','INTERNO','DOMINIO','MARCA','MODELO','UTILIDAD','CARROZADO'],
    tipo_base: 'Carrozado'
  },
  {
    tab_id: 'incidentes',
    nombre: 'Siniestros',
    columnas: ['INTERNO','INF','3RO LESIONADOS','DOMINIO','NRO STRO','FECHA','HORA','CARACTERISTICAS','DEPENDENCIA'],
    tipo_base: 'Incidentes'
  },
  {
    tab_id: 'bo_tra_mo',
    nombre: 'bo-tra-mo',
    columnas: ['MARCA / MODELO','INTERNO','TIPO','ESTADO','AVERIA','DESCRIPCION','DEPENDENCIA ACTUAL'],
    tipo_base: 'bo-tra-mo'
  },
  {
    tab_id: 'gh_ytorres',
    nombre: 'GH yTorres',
    columnas: ['DEPENDENCIA','MARCA','MODELO','POTENCIA','FASES','MOVIL PARA TRANSLADO','PARA EL SERVICIO','FUERA DE SERVICIO','TIPO'],
    tipo_base: 'GH yTorres'
  },
  {
    tab_id: 'historicos',
    nombre: 'Historicos',
    columnas: ['FECHA SOLICITUD','INTERNO','DOMINIO','MARCA','KM','DEPENDENCIA','DESCRIPCION','FECHA ASIGNACION','INGRESO','EGRESO','TALLER'],
    tipo_base: 'Historicos'
  }
];

const ALIASES = {
  grilla: ['cache/parrilla.json'],
  bo_tra_mo: ['cache/bo-tra-mo.json']
};

function remoteCandidates(relpath) {
  const clean = String(relpath || '').replace(/^\/+/, '');
  return [
    `https://raw.githubusercontent.com/${GITHUB_OWNER}/${GITHUB_REPO}/${GITHUB_BRANCH}/${clean}`,
    `https://cdn.jsdelivr.net/gh/${GITHUB_OWNER}/${GITHUB_REPO}@${GITHUB_BRANCH}/${clean}`,
    `https://github.com/${GITHUB_OWNER}/${GITHUB_REPO}/raw/refs/heads/${GITHUB_BRANCH}/${clean}`
  ];
}

function openDb() {
  if (typeof window === 'undefined' || !('indexedDB' in window)) return Promise.resolve(null);
  return new Promise((resolve) => {
    const request = window.indexedDB.open('flota-web-cache', 1);
    request.onupgradeneeded = () => {
      const db = request.result;
      if (!db.objectStoreNames.contains('json')) db.createObjectStore('json');
    };
    request.onsuccess = () => resolve(request.result);
    request.onerror = () => resolve(null);
  });
}

async function readLocal(key) {
  if (typeof window === 'undefined') return null;
  const db = await openDb();
  if (db) {
    const value = await new Promise((resolve) => {
      const tx = db.transaction('json', 'readonly');
      const req = tx.objectStore('json').get(key);
      req.onsuccess = () => resolve(req.result ?? null);
      req.onerror = () => resolve(null);
    });
    db.close();
    if (value) return value;
  }
  try {
    const raw = window.localStorage.getItem(key);
    return raw ? JSON.parse(raw) : null;
  } catch {
    return null;
  }
}

async function writeLocal(key, data) {
  if (typeof window === 'undefined') return;
  const db = await openDb();
  if (db) {
    await new Promise((resolve) => {
      const tx = db.transaction('json', 'readwrite');
      tx.objectStore('json').put(data, key);
      tx.oncomplete = () => resolve();
      tx.onerror = () => resolve();
      tx.onabort = () => resolve();
    });
    db.close();
    return;
  }
  try {
    window.localStorage.setItem(key, JSON.stringify(data));
  } catch {
    // Sin cache local disponible: la app sigue funcionando online.
  }
}

async function requestJson(relpath) {
  let lastError;
  for (const url of remoteCandidates(relpath)) {
    try {
      const response = await fetch(url, { cache: 'no-store' });
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      const data = await response.json();
      return { data, url };
    } catch (error) {
      lastError = error;
    }
  }
  throw lastError || new Error('No se pudo descargar el JSON.');
}

async function fetchManifest({ force = false } = {}) {
  const key = 'flota-web:cache/tab_config.json';
  try {
    const { data, url } = await requestJson('cache/tab_config.json');
    if (!data || !Array.isArray(data.tabs)) throw new Error('Manifest inválido');
    await writeLocal(key, data);
    return { data, source: 'remote', url };
  } catch (error) {
    const cached = await readLocal(key);
    if (cached && Array.isArray(cached.tabs)) return { data: cached, source: 'local', error };
    return { data: { version: 1, tabs: DEFAULT_TABS }, source: 'default', error };
  }
}

async function fetchTab(tabId) {
  const paths = [`cache/${tabId}.json`, ...(ALIASES[tabId] || [])];
  const key = `flota-web:cache/${tabId}.json`;
  let lastError;

  for (const path of paths) {
    try {
      const { data, url } = await requestJson(path);
      if (!data || !Array.isArray(data.columnas) || !Array.isArray(data.filas)) {
        throw new Error('Formato de grilla inválido');
      }
      await writeLocal(key, data);
      return { data, source: 'remote', url };
    } catch (error) {
      lastError = error;
    }
  }

  const cached = await readLocal(key);
  if (cached && Array.isArray(cached.columnas) && Array.isArray(cached.filas)) {
    return { data: cached, source: 'local', error: lastError };
  }

  return {
    data: { nombre: tabId, version: 1, actualizado_en: '-', columnas: [], filas: [] },
    source: 'empty',
    error: lastError
  };
}

function IconButton({ icon, label, onClick, disabled = false, active = false, className = '' }) {
  return (
    <button
      type="button"
      className={`toolbar-button ${active ? 'active' : ''} ${className}`}
      onClick={onClick}
      disabled={disabled}
      title={label}
      aria-label={label}
    >
      {icon ? <img src={icon} alt="" aria-hidden="true" /> : <span className="toolbar-fallback">{label}</span>}
      <span className="toolbar-label">{label}</span>
    </button>
  );
}

function Modal({ open, title, children, onClose, wide = false }) {
  useEffect(() => {
    if (!open) return undefined;
    const onKey = (event) => {
      if (event.key === 'Escape') onClose?.();
    };
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [open, onClose]);

  if (!open) return null;

  return (
    <div className="modal-backdrop" onMouseDown={(e) => e.target === e.currentTarget && onClose?.()}>
      <section className={`modal ${wide ? 'modal-wide' : ''}`} role="dialog" aria-modal="true" aria-label={title}>
        <header className="modal-header">
          <h2>{title}</h2>
          <button className="icon-close" type="button" onClick={onClose} aria-label="Cerrar">×</button>
        </header>
        <div className="modal-body">{children}</div>
      </section>
    </div>
  );
}


const UI = '/assets/ui';
const ACCENTS = ['#b3533a', '#b4232f', '#315d8f', '#2f6f57', '#76528b'];

function normalizeInterno(value) {
  return norm(value).toUpperCase().replace(/\s+/g, '');
}

function imagesForRecord(record) {
  const key = normalizeInterno(record?.INTERNO);
  if (!key) return [];
  return vehicleIndex[key] || [];
}

function filterRows(rows, search, filterColumn, filterValue) {
  const q = normalizeSearch(search);
  const fv = normalizeSearch(filterValue);
  return (rows || []).filter((row) => {
    if (filterColumn && fv) {
      if (normalizeSearch(row?.[filterColumn]) !== fv) return false;
    }
    if (!q) return true;
    return Object.values(row || {}).some((value) => normalizeSearch(value).includes(q));
  });
}

function getPrimaryColumns(columns, row) {
  const preferred = ['INTERNO','DEPENDENCIA','DEPENDENCIA ACTUAL','ESTADO','MARCA','MODELO','UTILIDAD','DOMINIO','DESCRIPCION','OBSERVACIONES','TALLER'];
  const ordered = [...preferred.filter((c) => columns.includes(c)), ...columns.filter((c) => !preferred.includes(c))];
  return ordered.filter((c) => norm(row?.[c])).slice(0, 7);
}

function FlotaApp() {
  const [tabs, setTabs] = useState([]);
  const [datasets, setDatasets] = useState({});
  const [activeId, setActiveId] = useState('grilla');
  const [search, setSearch] = useState('');
  const [filterColumn, setFilterColumn] = useState('');
  const [filterValue, setFilterValue] = useState('');
  const [selected, setSelected] = useState(null);
  const [cellPreview, setCellPreview] = useState(null);
  const [loading, setLoading] = useState(true);
  const [syncInfo, setSyncInfo] = useState({ source: 'remote', at: null, errors: 0 });
  const [theme, setTheme] = useState('light');
  const [accentIndex, setAccentIndex] = useState(0);
  const [hiddenColumns, setHiddenColumns] = useState({});
  const [modal, setModal] = useState(null);
  const [viewerIndex, setViewerIndex] = useState(0);
  const [installPrompt, setInstallPrompt] = useState(null);
  const [appInstalled, setAppInstalled] = useState(false);
  const [updatingApp, setUpdatingApp] = useState(false);

  const activeTab = useMemo(() => tabs.find((tab) => tab.tab_id === activeId) || tabs[0] || null, [tabs, activeId]);
  const activeData = datasets[activeId] || { columnas: activeTab?.columnas || [], filas: [], actualizado_en: '-' };
  const columns = activeData.columnas?.length ? activeData.columnas : activeTab?.columnas || [];
  const visibleColumns = columns.filter((column) => !(hiddenColumns[activeId] || []).includes(column));
  const filteredRows = useMemo(() => filterRows(activeData.filas, search, filterColumn, filterValue), [activeData.filas, search, filterColumn, filterValue]);
  const filterValues = useMemo(() => uniqueValues(activeData.filas, filterColumn), [activeData.filas, filterColumn]);
  const selectedImages = useMemo(() => imagesForRecord(selected), [selected]);
  const mainImage = selectedImages[viewerIndex] || selectedImages[0] || null;

  const syncAll = useCallback(async () => {
    setLoading(true);
    let errors = 0;
    try {
      const manifestResult = await fetchManifest({ force: true });
      const remoteTabs = (manifestResult.data.tabs || []).filter((t) => !['servis','service','servicio','servicios','novedades','registro'].includes(String(t.tab_id || '').toLowerCase()));
      setTabs(remoteTabs);
      if (!remoteTabs.some((t) => t.tab_id === activeId)) setActiveId(remoteTabs[0]?.tab_id || 'grilla');

      const results = await Promise.all(remoteTabs.map(async (tab) => {
        const result = await fetchTab(tab.tab_id);
        if (result.source === 'empty') errors += 1;
        return [tab.tab_id, result];
      }));

      const next = {};
      let localCount = manifestResult.source === 'local' ? 1 : 0;
      for (const [id, result] of results) {
        next[id] = result.data;
        if (result.source === 'local') localCount += 1;
      }
      setDatasets(next);
      setSyncInfo({
        source: errors ? 'partial' : localCount ? 'mixed' : 'remote',
        at: new Date(),
        errors
      });
    } catch {
      setSyncInfo({ source: 'error', at: new Date(), errors: errors + 1 });
    } finally {
      setLoading(false);
    }
  }, [activeId]);

  useEffect(() => {
    const savedTheme = window.localStorage.getItem('flota-web:theme');
    const savedAccent = Number(window.localStorage.getItem('flota-web:accent') || 0);
    if (savedTheme === 'dark' || savedTheme === 'light') setTheme(savedTheme);
    if (Number.isFinite(savedAccent)) setAccentIndex(Math.abs(savedAccent) % ACCENTS.length);

    const standalone = window.matchMedia?.('(display-mode: standalone)')?.matches || window.navigator.standalone === true;
    if (standalone || window.localStorage.getItem('flota-web:installed') === '1') setAppInstalled(true);

    const beforeInstall = (event) => {
      event.preventDefault();
      setInstallPrompt(event);
    };
    const onInstalled = () => {
      setAppInstalled(true);
      setInstallPrompt(null);
      window.localStorage.setItem('flota-web:installed', '1');
    };
    window.addEventListener('beforeinstallprompt', beforeInstall);
    window.addEventListener('appinstalled', onInstalled);
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('/sw.js').catch(() => {});
    }
    syncAll();
    return () => {
      window.removeEventListener('beforeinstallprompt', beforeInstall);
      window.removeEventListener('appinstalled', onInstalled);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    document.documentElement.dataset.theme = theme;
    document.documentElement.style.setProperty('--accent', ACCENTS[accentIndex]);
    window.localStorage.setItem('flota-web:theme', theme);
    window.localStorage.setItem('flota-web:accent', String(accentIndex));
  }, [theme, accentIndex]);

  useEffect(() => {
    setFilterColumn('');
    setFilterValue('');
    setSelected(null);
    setCellPreview(null);
  }, [activeId]);

  useEffect(() => setViewerIndex(0), [selected]);

  function selectRow(row, column = null) {
    setSelected(row);
    if (column) setCellPreview({ column, value: norm(row?.[column]) });
  }

  function clearFilters() {
    setSearch('');
    setFilterColumn('');
    setFilterValue('');
  }

  function toggleColumn(column) {
    setHiddenColumns((current) => {
      const now = new Set(current[activeId] || []);
      if (now.has(column)) now.delete(column);
      else now.add(column);
      return { ...current, [activeId]: [...now] };
    });
  }

  function showAllColumns() {
    setHiddenColumns((current) => ({ ...current, [activeId]: [] }));
  }

  async function installApp() {
    if (!installPrompt) return;
    await installPrompt.prompt();
    await installPrompt.userChoice.catch(() => null);
    setInstallPrompt(null);
  }

  async function updateApp() {
    if (updatingApp) return;
    setUpdatingApp(true);
    try {
      if ('serviceWorker' in navigator) {
        const regs = await navigator.serviceWorker.getRegistrations();
        await Promise.all(regs.map((reg) => reg.update().catch(() => null)));
      }
      await syncAll().catch(() => null);
      const url = new URL(window.location.href);
      url.searchParams.set('actualizar', Date.now().toString());
      window.location.replace(url.toString());
    } catch (_) {
      window.location.reload();
    }
  }

  const shareUrl = typeof window !== 'undefined' ? `${window.location.origin}/` : 'https://flotas-caba.pages.dev/';
  const shareText = 'Consulta de Flota · Oficina Coordinación y Control de Flota';
  const whatsappShareUrl = `https://wa.me/?text=${encodeURIComponent(`${shareText}\n${shareUrl}`)}`;
  const emailShareUrl = `mailto:?subject=${encodeURIComponent('Consulta de Flota')}&body=${encodeURIComponent(`${shareText}\n\n${shareUrl}`)}`;
  const qrShareUrl = `https://api.qrserver.com/v1/create-qr-code/?size=260x260&margin=12&data=${encodeURIComponent(shareUrl)}`;

  async function shareGeneral() {
    try {
      if (navigator.share) {
        await navigator.share({ title: 'Consulta de Flota', text: shareText, url: shareUrl });
        return;
      }
      if (navigator.clipboard?.writeText) {
        await navigator.clipboard.writeText(shareUrl);
        window.alert('Enlace copiado.');
        return;
      }
    } catch (error) {
      if (error?.name === 'AbortError') return;
    }
    window.prompt('Copiar enlace:', shareUrl);
  }

  const historyRows = useMemo(() => {
    const interno = normalizeInterno(selected?.INTERNO);
    if (!interno) return [];
    const rows = [];
    for (const tab of tabs) {
      for (const row of datasets[tab.tab_id]?.filas || []) {
        if (normalizeInterno(row.INTERNO) === interno) rows.push({ tab: tab.nombre, row });
      }
    }
    return rows;
  }, [selected, tabs, datasets]);

  const statistics = useMemo(() => {
    const rows = activeData.filas || [];
    const candidates = ['ESTADO','DEPENDENCIA ACTUAL','DEPENDENCIA','TALLER','TIPO'];
    const column = candidates.find((c) => columns.includes(c)) || columns[0];
    if (!column) return { column: '', items: [] };
    const counts = new Map();
    for (const row of rows) {
      const label = norm(row[column]) || '(vacío)';
      counts.set(label, (counts.get(label) || 0) + 1);
    }
    const items = [...counts.entries()].map(([label, count]) => ({ label, count })).sort((a, b) => b.count - a.count).slice(0, 15);
    return { column, items };
  }, [activeData.filas, columns]);

  const sourceLabel = syncInfo.source === 'remote'
    ? 'GitHub actualizado'
    : syncInfo.source === 'mixed'
      ? 'GitHub + copia local'
      : syncInfo.source === 'partial'
        ? 'Actualización parcial'
        : syncInfo.source === 'error'
          ? 'Sin conexión'
          : 'Copia local';

  return (
    <main className="app-shell">
      <section className="control-card">
        <div className="section-title-row">
          <div>
            <p className="eyebrow">Flota · versión web</p>
            <h1>OFICINA COORDINACIÓN Y CONTROL DE FLOTA</h1>
          </div>
          <div className="sync-share-row">
            <div className={`sync-chip ${syncInfo.source}`} title={syncInfo.at ? `Última comprobación: ${syncInfo.at.toLocaleString('es-AR')}` : ''}>
              <span className="sync-dot" /> {loading ? 'Actualizando…' : sourceLabel}
            </div>
            <button type="button" className="share-trigger" onClick={() => setModal('share')} title="Compartir" aria-label="Compartir">
              <svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="18" cy="5" r="2.5"></circle><circle cx="6" cy="12" r="2.5"></circle><circle cx="18" cy="19" r="2.5"></circle><path d="M8.2 10.8 15.8 6.2M8.2 13.2l7.6 4.6"></path></svg>
            </button>
          </div>
        </div>

        <div className="filter-row">
          <div className="brand-logo institutional"><img src={`${UI}/institucional.webp`} alt="Institucional" /></div>
          <label className="field field-search">
            <span>Buscar</span>
            <input value={search} onChange={(e) => setSearch(e.target.value)} placeholder="Búsqueda libre en la solapa activa…" />
          </label>
          <label className="field">
            <span>Columna</span>
            <select value={filterColumn} onChange={(e) => { setFilterColumn(e.target.value); setFilterValue(''); }}>
              <option value="">Todas</option>
              {columns.map((column) => <option key={column} value={column}>{column}</option>)}
            </select>
          </label>
          <label className="field">
            <span>Valor</span>
            <select value={filterValue} onChange={(e) => setFilterValue(e.target.value)} disabled={!filterColumn}>
              <option value="">Todos</option>
              {filterValues.map((value) => <option key={value} value={value}>{value}</option>)}
            </select>
          </label>
          <div className="brand-logo flota"><img src={`${UI}/logo-flota.png`} alt="Logo Flota" /></div>
        </div>

        <div className="toolbar">
          <div className="toolbar-left">
            <IconButton icon={`${UI}/ver.png`} label="Ver columnas" onClick={() => setModal('columns')} />
            <IconButton icon={`${UI}/ficha-tecnica.png`} label="Ficha" onClick={() => setModal('record')} disabled={!selected} />
            <IconButton icon={`${UI}/filtros.png`} label="Limpiar filtros" onClick={clearFilters} />
          </div>
          <div className="toolbar-right">
            <IconButton icon={`${UI}/exportar-pdf.png`} label="PDF" onClick={() => window.print()} />
            <IconButton icon={`${UI}/historial.png`} label="Historial" onClick={() => setModal('history')} disabled={!selected?.INTERNO} />
            <IconButton icon={`${UI}/estadistica.png`} label="Estadística" onClick={() => setModal('stats')} />
            <IconButton icon={`${UI}/descargar.png`} label={loading ? 'Actualizando' : 'Actualizar'} onClick={syncAll} disabled={loading} className={loading ? 'spin-icon' : ''} />
            <IconButton icon={`${UI}/modo-noche.png`} label="Modo noche" onClick={() => setTheme('dark')} active={theme === 'dark'} />
            <IconButton icon={`${UI}/modo-dia.png`} label="Modo día" onClick={() => setTheme('light')} active={theme === 'light'} />
            <button type="button" className="palette-button" onClick={() => setAccentIndex((accentIndex + 1) % ACCENTS.length)} title="Cambiar color" aria-label="Cambiar color">
              <span style={{ background: ACCENTS[accentIndex] }} />
              <small>Color</small>
            </button>
            {installPrompt && !appInstalled
              ? <button type="button" className="install-button" onClick={installApp}>Instalar</button>
              : appInstalled && <button type="button" className="install-button update-button" onClick={updateApp} disabled={updatingApp}>{updatingApp ? 'Actualizando…' : 'Actualizar'}</button>}
          </div>
        </div>
      </section>

      <nav className="tabs" aria-label="Secciones">
        {tabs.map((tab) => (
          <button key={tab.tab_id} type="button" className={tab.tab_id === activeId ? 'active' : ''} onClick={() => setActiveId(tab.tab_id)}>
            {tab.nombre}
          </button>
        ))}
      </nav>

      <section className="workspace">
        <div className="grid-panel">
          <div className="table-meta">
            <div><strong>{activeTab?.nombre || 'Datos'}</strong><span>{filteredRows.length} visibles / {(activeData.filas || []).length} filas</span></div>
            <span>JSON: {compactDate(activeData.actualizado_en)}</span>
          </div>

          <div className="table-scroll desktop-table">
            <table>
              <thead>
                <tr>{visibleColumns.map((column) => <th key={column}>{column}</th>)}</tr>
              </thead>
              <tbody>
                {filteredRows.map((row, rowIndex) => {
                  const isSelected = row === selected;
                  return (
                    <tr key={`${activeId}-${rowIndex}`} className={isSelected ? 'selected' : ''} onClick={() => selectRow(row)}>
                      {visibleColumns.map((column) => (
                        <td key={column} onClick={(event) => { event.stopPropagation(); selectRow(row, column); }} title={norm(row[column])}>
                          {column === 'ESTADO' && norm(row[column]) ? <span className={`state-pill ${statusClass(row[column])}`}>{norm(row[column])}</span> : norm(row[column])}
                        </td>
                      ))}
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>

          <div className="mobile-list">
            {filteredRows.map((row, rowIndex) => {
              const cardColumns = getPrimaryColumns(visibleColumns, row);
              return (
                <article key={`${activeId}-card-${rowIndex}`} className={`mobile-row-card ${row === selected ? 'selected' : ''}`} onClick={() => selectRow(row)}>
                  <header>
                    <strong>{norm(row.INTERNO) ? `Interno ${norm(row.INTERNO)}` : recordTitle(row, activeTab?.nombre)}</strong>
                    {norm(row.ESTADO) && <span className={`state-pill ${statusClass(row.ESTADO)}`}>{norm(row.ESTADO)}</span>}
                  </header>
                  <dl>
                    {cardColumns.filter((column) => column !== 'INTERNO' && column !== 'ESTADO').map((column) => (
                      <div key={column} onClick={(event) => { event.stopPropagation(); selectRow(row, column); }}>
                        <dt>{column}</dt><dd>{norm(row[column])}</dd>
                      </div>
                    ))}
                  </dl>
                </article>
              );
            })}
          </div>

          {!loading && filteredRows.length === 0 && <div className="empty-state">No hay registros que coincidan con los filtros.</div>}
          {loading && !activeData.filas?.length && <div className="empty-state">Descargando información desde GitHub…</div>}
        </div>

        <aside className="detail-panel">
          <section className="photo-card">
            {mainImage ? (
              <button type="button" className="main-photo" onClick={() => setModal('viewer')}>
                <img src={mainImage.src} alt={`Interno ${norm(selected?.INTERNO)} · vista ${mainImage.variant}`} />
              </button>
            ) : (
              <div className="main-photo placeholder"><span>{selected ? 'Sin imagen disponible' : 'Seleccione una unidad'}</span></div>
            )}
            <div className="thumbs">
              {selectedImages.map((image, index) => (
                <button type="button" key={`${image.variant}-${image.src}`} className={index === viewerIndex ? 'active' : ''} onClick={() => setViewerIndex(index)}>
                  <img src={image.src} alt={`Vista ${image.variant}`} loading="lazy" />
                  <span>{image.variant}</span>
                </button>
              ))}
            </div>
          </section>

          <section className="info-card">
            <img className="info-watermark" src={`${UI}/fondo.webp`} alt="" aria-hidden="true" />
            <div className="info-content">
              <h2>{selected ? recordTitle(selected, activeTab?.nombre) : 'Seleccione una unidad'}</h2>
              {selected && <>
                <p><strong>Interno:</strong> {norm(selected.INTERNO) || '-'} <span className="sep">·</span> <strong>Estado:</strong> {norm(selected.ESTADO) || '-'}</p>
                <p><strong>Marca:</strong> {norm(selected.MARCA) || '-'} <span className="sep">·</span> <strong>Modelo:</strong> {norm(selected.MODELO) || '-'}</p>
                <p><strong>Actual:</strong> {getDependency(selected)}</p>
                {(norm(selected.OBSERVACIONES) || norm(selected.DETALLE) || norm(selected.DESCRIPCION)) && <p className="note"><strong>Obs.:</strong> {norm(selected.OBSERVACIONES) || norm(selected.DETALLE) || norm(selected.DESCRIPCION)}</p>}
              </>}
            </div>
          </section>

          <section className="preview-card">
            <h3>{cellPreview ? `Contenido completo · ${cellPreview.column}` : 'Contenido de celda'}</h3>
            <div>{cellPreview?.value || 'Seleccione una celda para ver el contenido completo.'}</div>
          </section>
        </aside>
      </section>

      <footer className="status-footer">
        <span>{activeTab?.nombre || 'Flota'}: {filteredRows.length} visibles / {(activeData.filas || []).length} filas</span>
        <span>Web responsive · PWA · datos desde GitHub</span>
      </footer>

      <Modal open={modal === 'share'} title="Compartir Flota" onClose={() => setModal(null)} sheet={false}>
        <div className="share-content">
          <div className="share-methods">
            <button type="button" onClick={shareGeneral} className="share-method">
              <span className="share-method-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="18" cy="5" r="2.5"></circle><circle cx="6" cy="12" r="2.5"></circle><circle cx="18" cy="19" r="2.5"></circle><path d="M8.2 10.8 15.8 6.2M8.2 13.2l7.6 4.6"></path></svg></span>
              <strong>Compartir</strong>
              <small>Opciones del dispositivo</small>
            </button>
            <a className="share-method" href={whatsappShareUrl} target="_blank" rel="noreferrer">
              <span className="share-method-icon share-method-letter">W</span>
              <strong>WhatsApp</strong>
              <small>Enviar el enlace</small>
            </a>
            <a className="share-method" href={emailShareUrl}>
              <span className="share-method-icon share-method-letter">@</span>
              <strong>Email</strong>
              <small>Enviar por correo</small>
            </a>
          </div>
          <div className="share-qr">
            <img src={qrShareUrl} alt="Código QR para compartir Consulta de Flota" />
            <div>
              <strong>Compartir con QR</strong>
              <span>Escanear para abrir la aplicación.</span>
            </div>
          </div>
        </div>
      </Modal>

      <Modal open={modal === 'columns'} title={`Columnas · ${activeTab?.nombre || ''}`} onClose={() => setModal(null)}>
        <div className="column-picker">
          {columns.map((column) => (
            <label key={column}>
              <input type="checkbox" checked={!((hiddenColumns[activeId] || []).includes(column))} onChange={() => toggleColumn(column)} />
              <span>{column}</span>
            </label>
          ))}
        </div>
        <div className="modal-actions"><button type="button" onClick={showAllColumns}>Mostrar todas</button></div>
      </Modal>

      <Modal open={modal === 'record'} title={`Ficha · Interno ${norm(selected?.INTERNO) || '-'}`} onClose={() => setModal(null)} wide>
        {selected && <div className="record-sheet">
          {columns.filter((column) => norm(selected[column])).map((column) => (
            <div key={column}><span>{column}</span><strong>{norm(selected[column])}</strong></div>
          ))}
        </div>}
      </Modal>

      <Modal open={modal === 'history'} title={`Historial · Interno ${norm(selected?.INTERNO) || '-'}`} onClose={() => setModal(null)} wide>
        <div className="history-list">
          {historyRows.map((item, index) => (
            <article key={`${item.tab}-${index}`}>
              <header><strong>{item.tab}</strong></header>
              <div className="history-fields">
                {Object.entries(item.row).filter(([, value]) => norm(value)).slice(0, 12).map(([key, value]) => <p key={key}><span>{key}</span>{norm(value)}</p>)}
              </div>
            </article>
          ))}
          {!historyRows.length && <div className="empty-state">No se encontraron registros para este interno.</div>}
        </div>
      </Modal>

      <Modal open={modal === 'stats'} title={`Estadística · ${activeTab?.nombre || ''}`} onClose={() => setModal(null)}>
        <p className="stats-subtitle">Distribución por <strong>{statistics.column || 'campo'}</strong></p>
        <div className="stats-list">
          {statistics.items.map((item) => {
            const max = statistics.items[0]?.count || 1;
            return <div className="stat-row" key={item.label}>
              <div><span>{item.label}</span><strong>{item.count}</strong></div>
              <div className="stat-track"><span style={{ width: `${Math.max(3, item.count / max * 100)}%` }} /></div>
            </div>;
          })}
        </div>
      </Modal>

      <Modal open={modal === 'viewer'} title={`Interno ${norm(selected?.INTERNO) || ''}`} onClose={() => setModal(null)} wide>
        <div className="viewer">
          {mainImage && <img src={mainImage.src} alt={`Vista ${mainImage.variant}`} />}
          <div className="viewer-controls">
            <button type="button" onClick={() => setViewerIndex((viewerIndex - 1 + selectedImages.length) % selectedImages.length)} disabled={selectedImages.length < 2}>← Anterior</button>
            <span>{selectedImages.length ? `${viewerIndex + 1} / ${selectedImages.length}` : ''}</span>
            <button type="button" onClick={() => setViewerIndex((viewerIndex + 1) % selectedImages.length)} disabled={selectedImages.length < 2}>Siguiente →</button>
          </div>
        </div>
      </Modal>
    </main>
  );
}


const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<FlotaApp />);
