#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'em-websocket'
require 'set'
require 'webrick'
require 'json'
require 'uri'

# WebSocket ポート
WS_PORT = 8888
# HTTP ポート
HTTP_PORT = 8889
# クライアント集合
clients = Set.new
# 現在選択中の曲URL（簡易的にグローバル管理）
selected_url = nil

# === HTTPサーバー（音楽ファイルと JSON を提供）===
http_server = WEBrick::HTTPServer.new(
  Port: HTTP_PORT,
  BindAddress: '0.0.0.0',         # ← これを追加！
  DocumentRoot: './public',
  AccessLog: [],
  Logger: WEBrick::Log.new("/dev/null")
)

http_server.mount_proc '/music_list.json' do |req, res|
  files = Dir.glob("public/music/*.{mp3,wav,ogg}")
             .map { |f| File.basename(f) }
             .sort_by { |f| f[/^\d+/].to_i }  # ← 番号の順に並べるよ！
  res['Content-Type'] = 'application/json'
  res['Access-Control-Allow-Origin'] = '*'
  res.body = { files: files }.to_json
end

http_server.mount_proc '/music/' do |req, res|
  path = "./public/music/#{File.basename(req.path)}"
  if File.exist?(path)
    res['Content-Type'] = 'audio/mpeg'
    res['Access-Control-Allow-Origin'] = '*'
    res.body = File.open(path, 'rb') { |f| f.read }
  else
    res.status = 404
    res.body = 'Not Found'
  end
end

# HTTP サーバーをバックグラウンドで開始
Thread.new { http_server.start }

puts "WebSocket server starting on port #{WS_PORT}..."
puts "HTTP server running on http://localhost:#{HTTP_PORT}/"

# Ctrl+C で両サーバーを終了
trap('INT') do
  puts "\n[INTERRUPT] シャットダウン中..."
  http_server.shutdown
  EM.stop if EM.reactor_running?
end

# WebSocket サーバー
EM.run do
  EM::WebSocket.start(host: "0.0.0.0", port: WS_PORT) do |ws_conn|
    ws_conn.onopen do
      clients << ws_conn
      ws_conn.send({ type: "info", message: "うっす！ WebSocket 接続完了" }.to_json)
      puts "[OPEN] クライアント接続: #{clients.size} 名"
    end
    
    ws_conn.onmessage do |msg|
      puts "[RECV] #{msg}"
      begin
        data = JSON.parse(msg)
        case data["type"]
        when "select"
          selected_url = "http://localhost:#{HTTP_PORT}/music/#{URI.encode_www_form_component(data["file"])}"
          clients.each { |c| c.send({ type: "select", url: selected_url }.to_json) }

        when "play"
          if selected_url
            clients.each { |c| c.send({ type: "play", url: selected_url }.to_json) }
          end

        when "stop"
          clients.each { |c| c.send({ type: "stop" }.to_json) }

        when "reset"
          # 🔽 リセット処理をここに追加
          clients.each { |c| c.send({ type: "announce", queue: [] }.to_json) }

        when "raise"
          clients.each { |c| c.send({ type: "raise", name: data["name"] }.to_json) }
          
        else
          # 未知のactionはそのまま送信
          clients.each { |c| c.send(msg) unless c == ws_conn }
        end

      rescue JSON::ParserError
        # JSON解析できないメッセージはそのまま転送（または無視）
        clients.each { |c| c.send(msg) unless c == ws_conn }
      end
    end

    ws_conn.onclose do
      clients.delete(ws_conn)
      puts "[CLOSE] 切断: 残り #{clients.size} 名"
    end
  end
end
