# encoding: UTF-8
begin
  puts "###DZW-COMP2GROUP2-20260920"
  m = Sketchup.active_model
  bk = 'E:/도진팩토리/3D스캔및티칭시스템/_자동화/autosave/BACKUP_before_comp2group2.skp'
  m.save_copy(bk)
  puts "BACKUP=#{bk}"
  ents = lambda { |s| s.is_a?(Sketchup::Group) ? s.entities : s.definition.entities }
  lab = lambda do |s|
    nm = (s.respond_to?(:name) ? s.name.to_s : '')
    dn = s.is_a?(Sketchup::ComponentInstance) ? s.definition.name.to_s : ''
    nm.empty? ? (dn.empty? ? '(무명)' : dn) : nm
  end
  sig = ['조립부원판_20260919', 'DJ1250-윈치받침', '하부보강_2절곡_A_20260919', '연결브라켓_L_A_20260919']
  cands = []
  walk = nil
  walk = lambda do |ent, path, depth|
    (ent.grep(Sketchup::Group) + ent.grep(Sketchup::ComponentInstance)).each do |s|
      l = lab.call(s)
      kids = (ents.call(s).grep(Sketchup::Group) + ents.call(s).grep(Sketchup::ComponentInstance)).map { |k| lab.call(k) }
      hit = sig.count { |x| kids.include?(x) }
      cands << ["#{path}/#{l}", s, hit, kids] if hit >= 2
      walk.call(ents.call(s), "#{path}/#{l}", depth + 1) if depth < 3
    end
  end
  walk.call(m.entities, '', 0)
  puts "커버 후보 #{cands.length}개"
  cands.each { |p, s, h, k| puts "  #{p} #{s.class} 시그니처일치=#{h} 자식#{k.length}개: #{k.first(12).inspect}" }
  if cands.empty?
    puts "STOP: 커버 후보 미발견(무수정)"
  else
    path, target, hit, kids0 = cands.max_by { |a| a[2] }
    if target.is_a?(Sketchup::Group)
      puts "== #{path} 는 이미 Sketchup::Group 입니다. 이름='#{target.name}' -> 변환 불필요(무수정, 저장 안 함)"
    else
      defn = target.definition
      inst = defn.instances.length
      par = target.parent
      pents = par.is_a?(Sketchup::Model) ? par.entities : par.entities
      b0 = target.bounds
      mn0 = b0.min.to_a.map { |v| v.to_mm.round(2) }
      mx0 = b0.max.to_a.map { |v| v.to_mm.round(2) }
      puts "대상 #{path} ComponentInstance 정의='#{defn.name}' 인스턴스수=#{inst}"
      puts "  전 bbox min=#{mn0.inspect} max=#{mx0.inspect} 자식#{kids0.length}개"
      if inst > 1
        puts "STOP: 같은 정의 인스턴스 #{inst}개 -> 다른 배치 영향 우려로 변환 안 함(무수정)"
      else
        m.start_operation('컴포넌트->그룹', true)
        res = target.explode
        keep = res.select { |e| e.valid? && (e.is_a?(Sketchup::Group) || e.is_a?(Sketchup::ComponentInstance) || e.is_a?(Sketchup::Edge) || e.is_a?(Sketchup::Face)) }
        g = pents.add_group(keep)
        g.name = '하부프레임커버'
        m.commit_operation
        b1 = g.bounds
        mn1 = b1.min.to_a.map { |v| v.to_mm.round(2) }
        mx1 = b1.max.to_a.map { |v| v.to_mm.round(2) }
        kids1 = (g.entities.grep(Sketchup::Group) + g.entities.grep(Sketchup::ComponentInstance)).map { |k| lab.call(k) }
        dmn = (0..2).map { |i| (mn1[i] - mn0[i]).abs }.max
        dmx = (0..2).map { |i| (mx1[i] - mx0[i]).abs }.max
        okk = dmn < 0.5 && dmx < 0.5 && kids1.length == kids0.length
        puts "== 결과 #{g.class} '#{g.name}' 자식#{kids1.length}개"
        puts "   후 bbox min=#{mn1.inspect} max=#{mx1.inspect} (편차 min#{dmn.round(3)} / max#{dmx.round(3)} mm)"
        puts "   자식: #{kids1.first(14).inspect}"
        puts "   판정: #{okk ? '위치·구성 불변 정상' : '이상 -> CEO 확인 필요'}"
        vw = m.active_view
        cam0 = vw.camera
        begin
          c = g.bounds.center
          vw.camera = Sketchup::Camera.new(Geom::Point3d.new(c.x - 2500.mm, c.y - 3000.mm, c.z - 1500.mm), c, Geom::Vector3d.new(0, 0, 1))
          f = 'E:/도진팩토리/3D스캔및티칭시스템/_자동화/inbox/_c2g2.png'
          vw.write_image(f, 1600, 1000, true)
          puts "   캡처=#{f} 존재=#{File.exist?(f)}"
        rescue Exception => e3
          puts "   캡처 실패 #{e3.message}"
        ensure
          vw.camera = cam0
        end
        ok = m.save
        puts "SAVE=#{ok.inspect} modified?=#{m.modified?.inspect}"
      end
    end
  end
  puts "DONE"
rescue Exception => e
  puts "EXC #{e.class}: #{e.message}"
  puts e.backtrace.first(6).join(" | ")
end
nil
