import re

with open("app/static/bim/index.html", "r", encoding="utf-8") as f:
    content = f.read()

# 1. Replace Waterstops (groupJoints)
waterstops_old = r"""      // Băng cản nước V250.*?const WATERSTOP_LINES = 4;.*?for \(const \[u, y\] of WATERSTOP_POS\.slice\(0, WATERSTOP_LINES\)\) \{.*?groupJoints\.add\(new THREE\.Mesh\(g, new THREE\.MeshStandardMaterial\(\{ color: 0xfacc15, side: THREE\.DoubleSide \}\)\)\);\s*\}"""
waterstops_new = """      // Băng cản nước V250
      const WATERSTOP_LINES = 4;
      const WATERSTOP_POS = [[-1.375, 0.55], [1.375, 0.55], [-1.375, 2.75], [1.375, 2.75]];
      for (const [u, y] of WATERSTOP_POS.slice(0, WATERSTOP_LINES)) {
        SEGMENT_RANGES.forEach(([a, b], k) => {
          const g = buildLoftGeometry((s) => [getPointAt(s, u, y - 0.125), getPointAt(s, u, y + 0.125)], a, b);
          const m = new THREE.Mesh(g, new THREE.MeshStandardMaterial({ color: 0xfacc15, side: THREE.DoubleSide }));
          m.userData.seg = k;
          groupJoints.add(m);
        });
      }"""
content = re.sub(waterstops_old, waterstops_new, content, flags=re.DOTALL)

# 2. Replace Foundation (groupFoundation)
foundation_old = r"""      // D\. Móng cống \(Đệm cát 10cm \+ Bê tông lót M100 rộng 3\.4m\).*?const foundationMesh = new THREE\.Mesh\(foundationGeom, foundationMat\);\s*groupFoundation\.add\(foundationMesh\);"""
foundation_new = """      // D. Móng cống (Đệm cát 10cm + Bê tông lót M100 rộng 3.4m)
      const foundationSegs = SEGMENT_RANGES.map(([a, b]) => {
        const m = new THREE.Mesh(buildLoftGeometry((s) => [
          getPointAt(s, -1.7, 0.0),
          getPointAt(s, 1.7, 0.0),
          getPointAt(s, 1.7, -0.2),
          getPointAt(s, -1.7, -0.2),
          getPointAt(s, -1.7, 0.0)
        ], a, b), foundationMat);
        groupFoundation.add(m);
        return m;
      });"""
content = re.sub(foundation_old, foundation_new, content, flags=re.DOTALL)

# 3. Replace Rebar (groupRebar)
rebar_old = r"""      // H\. Cốt thép \(Rebar cages\).*?const rebarVertices = \[\];.*?const rebarLines = new THREE\.LineSegments.*?groupRebar\.add\(rebarLines\);"""
rebar_new = """      // H. Cốt thép (Rebar cages)
      const rebarSegs = [];
      const longBarDefs = [
        { off: -1.35, y: 0.12 }, { off: 0.0, y: 0.12 }, { off: 1.35, y: 0.12 },
        { off: -1.35, y: 2.88 }, { off: 0.0, y: 2.88 }, { off: 1.35, y: 2.88 }
      ];
      SEGMENT_RANGES.forEach(([a, b]) => {
        const segVertices = [];
        for (let s = a + 0.5; s < b; s += 0.8) {
          const p1 = getPointAt(s, -1.35, 0.12);
          const p2 = getPointAt(s, 1.35, 0.12);
          const p3 = getPointAt(s, 1.35, 2.88);
          const p4 = getPointAt(s, -1.35, 2.88);
          segVertices.push(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);
          segVertices.push(p2.x, p2.y, p2.z, p3.x, p3.y, p3.z);
          segVertices.push(p3.x, p3.y, p3.z, p4.x, p4.y, p4.z);
          segVertices.push(p4.x, p4.y, p4.z, p1.x, p1.y, p1.z);
        }
        for (const bDef of longBarDefs) {
          for (let i = 0; i < sSamples.length - 1; i++) {
            const sA = sSamples[i];
            const sB = sSamples[i + 1];
            if (sA >= a - 1e-3 && sB <= b + 1e-3) {
              const ptA = getPointAt(sA, bDef.off, bDef.y);
              const ptB = getPointAt(sB, bDef.off, bDef.y);
              segVertices.push(ptA.x, ptA.y, ptA.z, ptB.x, ptB.y, ptB.z);
            }
          }
        }
        const geom = new THREE.BufferGeometry();
        geom.setAttribute('position', new THREE.Float32BufferAttribute(segVertices, 3));
        const mesh = new THREE.LineSegments(geom, new THREE.LineBasicMaterial({ color: 0xf59e0b, linewidth: 1.5 }));
        groupRebar.add(mesh);
        rebarSegs.push(mesh);
      });"""
content = re.sub(rebar_old, rebar_new, content, flags=re.DOTALL)

# 4. Replace Raycast Targets
raycast_old = r"""const raycastTargets = \[\s*\.\.\.culvertSegs, \.\.\.topSlabSegs,\s*foundationMesh, \.\.\.allLarsen,\s*\.\.\.groupManhole\.children\s*\];"""
raycast_new = """const raycastTargets = [
          ...culvertSegs, ...topSlabSegs,
          ...foundationSegs, ...allLarsen,
          ...groupManhole.children
        ];"""
content = re.sub(raycast_old, raycast_new, content, flags=re.DOTALL)

raycast_hit_old = r"""\} else if \(hit === foundationMesh\) \{"""
raycast_hit_new = """} else if (foundationSegs.includes(hit)) {"""
content = content.replace(raycast_hit_old, raycast_hit_new)

# 5. Update updateBim4DState
update_old = r"""      groupFoundation\.visible = day >= SEG_PLAN\[0\]\.lean\[0\];\s*groupRebar\.visible = day >= SEG_PLAN\[0\]\.lean\[0\];\s*groupJoints\.visible = day >= SEG_PLAN\[0\]\.wall\[0\];"""
update_new = """      groupFoundation.visible = true;
      groupRebar.visible = true;
      groupJoints.visible = true;
      
      foundationSegs.forEach((m, k) => {
        m.visible = day >= SEG_PLAN[k].lean[0];
      });
      rebarSegs.forEach((m, k) => {
        m.visible = day >= SEG_PLAN[k].lean[0];
      });
      groupJoints.children.forEach(m => {
        m.visible = day >= SEG_PLAN[m.userData.seg].wall[0];
      });"""
content = re.sub(update_old, update_new, content, flags=re.DOTALL)

with open("app/static/bim/index.html", "w", encoding="utf-8") as f:
    f.write(content)
print("Segments split successfully!")
