#!/usr/bin/env bash

# Run Flutter web (dev environment) with CORS-friendly local server.
# Builds the app using CanvasKit renderer and serves it from build/web on :8080.

set -euo pipefail

PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PORT="${PORT:-8080}"
BROWSER_PROFILE="${BROWSER_PROFILE:-/tmp/mypoint_web_dev}"

cd "${PROJECT_ROOT}"

kill_port() {
  local port="$1"
  lsof -i ":${port}" | awk 'NR>1 {print $2}' | xargs kill -9 2>/dev/null || true
}

set_env_dev() {
  echo "🔧 Switching to DEVELOPMENT environment..."
  local src="${PROJECT_ROOT}/assets/config/env_dev.json"
  local dest="${PROJECT_ROOT}/assets/config/env.json"
  if [ ! -f "${src}" ]; then
    echo "❌ ${src} not found" >&2
    exit 1
  fi
  cp "${src}" "${dest}"
  echo "📋 Current config:"
  cat "${dest}"
  echo ""
}

copy_x_app_sdk() {
  local src="node_modules/x-app-sdk/dist/index.es.js"
  local dest="build/web/js/x_app_sdk_bundle.js"
  if [ ! -f "${src}" ]; then
    echo "❌ x-app-sdk bundle not found at ${src}" >&2
    exit 1
  fi
  mkdir -p "$(dirname "${dest}")"
  cp "${src}" "${dest}"
  echo "✅ Copied x-app-sdk bundle."
}

compress_assets_for_dev() {
  local dir="${PROJECT_ROOT}/build/web"
  echo "🗜️  Compressing assets for 4G optimization (gzip + brotli)..."
  
  # Gzip compression (level 9 = maximum)
  if command -v gzip >/dev/null 2>&1; then
    echo "   → Creating .gz files (gzip -9)..."
    find "${dir}" -type f \( -name '*.js' -o -name '*.wasm' -o -name '*.css' -o -name '*.json' \) ! -name '*.gz' ! -name '*.br' -exec gzip -9 -kf {} \;
    echo "   ✅ Gzip compression completed"
  else
    echo "   ⚠️  gzip not available, skipping .gz artifacts"
  fi
  
  # Brotli compression (quality 11 = maximum) - better compression for 4G
  if command -v brotli >/dev/null 2>&1; then
    echo "   → Creating .br files (brotli -q 11)..."
    find "${dir}" -type f \( -name '*.js' -o -name '*.wasm' -o -name '*.css' -o -name '*.json' \) ! -name '*.gz' ! -name '*.br' -exec brotli -f -k -q 11 {} \;
    echo "   ✅ Brotli compression completed"
  else
    echo "   ⚠️  brotli not available, skipping .br artifacts"
  fi
  
  # Show compression stats for canvaskit.wasm if it exists
  local wasm_file="${dir}/canvaskit/chromium/canvaskit.wasm"
  if [ -f "${wasm_file}" ]; then
    local original_size=$(stat -f%z "${wasm_file}" 2>/dev/null || stat -c%s "${wasm_file}" 2>/dev/null || echo "0")
    local gz_size=0
    local br_size=0
    if [ -f "${wasm_file}.gz" ]; then
      gz_size=$(stat -f%z "${wasm_file}.gz" 2>/dev/null || stat -c%s "${wasm_file}.gz" 2>/dev/null || echo "0")
    fi
    if [ -f "${wasm_file}.br" ]; then
      br_size=$(stat -f%z "${wasm_file}.br" 2>/dev/null || stat -c%s "${wasm_file}.br" 2>/dev/null || echo "0")
    fi
    echo ""
    echo "📊 canvaskit.wasm compression stats:"
    echo "   Original: $(numfmt --to=iec-i --suffix=B ${original_size} 2>/dev/null || echo "${original_size} bytes")"
    if [ "${gz_size}" -gt 0 ]; then
      local gz_ratio=$(echo "scale=1; (${original_size} - ${gz_size}) * 100 / ${original_size}" | bc 2>/dev/null || echo "0")
      echo "   Gzip:    $(numfmt --to=iec-i --suffix=B ${gz_size} 2>/dev/null || echo "${gz_size} bytes") (${gz_ratio}% smaller)"
    fi
    if [ "${br_size}" -gt 0 ]; then
      local br_ratio=$(echo "scale=1; (${original_size} - ${br_size}) * 100 / ${original_size}" | bc 2>/dev/null || echo "0")
      echo "   Brotli:  $(numfmt --to=iec-i --suffix=B ${br_size} 2>/dev/null || echo "${br_size} bytes") (${br_ratio}% smaller)"
    fi
  fi
}

build_web() {
  echo "📦 Getting Flutter packages..."
  flutter pub get

  echo "🔨 Building Flutter web app (release, CanvasKit)..."
  flutter build web \
    --release \
    --pwa-strategy=none \
    --dart-define=FLUTTER_WEB_USE_SKIA=true \
    --dart-define=FLUTTER_WEB_USE_SKWASM=false \
    --no-wasm-dry-run
}

start_server() {
  python3 - "${PROJECT_ROOT}/build/web" "${PORT}" <<'PY' &
import http.server
import socketserver
import os
import sys

ROOT = sys.argv[1]
PORT = int(sys.argv[2])
os.chdir(ROOT)

class CORSRequestHandler(http.server.SimpleHTTPRequestHandler):
    def end_headers(self):
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With, Accept, Origin')
        # Add cache headers for static assets to speed up localhost loading
        cacheable_exts = ('.js', '.wasm', '.css', '.woff2', '.png', '.jpg', '.jpeg', '.svg', '.webp')
        if self.path.endswith(cacheable_exts):
            self.send_header('Cache-Control', 'public, max-age=3600')
        super().end_headers()

    def do_OPTIONS(self):
        self.send_response(200)
        self.end_headers()

    def do_GET(self):
        path = self.translate_path(self.path)
        if os.path.isdir(path):
            path = os.path.join(path, 'index.html')
        if not os.path.exists(path):
            self.path = '/index.html'
            path = self.translate_path(self.path)
        
        # Check for compressed versions (gzip/brotli) to optimize for 4G throttling
        accept_encoding = self.headers.get('Accept-Encoding', '')
        compressed_path = None
        encoding = None
        
        if os.path.exists(path):
            # Prefer brotli, then gzip
            if 'br' in accept_encoding and os.path.exists(path + '.br'):
                compressed_path = path + '.br'
                encoding = 'br'
            elif 'gzip' in accept_encoding and os.path.exists(path + '.gz'):
                compressed_path = path + '.gz'
                encoding = 'gzip'
        
        if compressed_path and encoding:
            # Serve compressed file
            try:
                with open(compressed_path, 'rb') as f:
                    content = f.read()
                
                self.send_response(200)
                # Set content type based on original file
                if path.endswith('.wasm'):
                    self.send_header('Content-Type', 'application/wasm')
                elif path.endswith('.js'):
                    self.send_header('Content-Type', 'application/javascript')
                elif path.endswith('.css'):
                    self.send_header('Content-Type', 'text/css')
                elif path.endswith('.json'):
                    self.send_header('Content-Type', 'application/json')
                
                self.send_header('Content-Encoding', encoding)
                self.send_header('Content-Length', str(len(content)))
                self.send_header('Vary', 'Accept-Encoding')
                self.end_headers()
                self.wfile.write(content)
                return
            except Exception as e:
                print(f"⚠️  Error serving compressed file: {e}")
                # Fall through to serve uncompressed
        
        # Serve uncompressed file
        return super().do_GET()

    def log_message(self, fmt, *args):
        print(f"🌐 {fmt % args}")

with socketserver.TCPServer(('', PORT), CORSRequestHandler) as httpd:
    print(f"🚀 Dev server running at http://localhost:{PORT}")
    print(f"📁 Serving from: {os.getcwd()}")
    print("🔧 CORS headers enabled (browser launched with web security disabled).")
    print("✅ Press Ctrl+C to stop.")
    httpd.serve_forever()
PY
  SERVER_PID=$!
}

open_browser() {
  local url="http://localhost:${PORT}"
  echo "🌐 Opening Chrome with CORS disabled at ${url}..."
  if command -v open >/dev/null 2>&1; then
    open -n -a "Google Chrome" --args --disable-web-security --user-data-dir="${BROWSER_PROFILE}" --disable-features=VizDisplayCompositor "${url}"
  elif command -v google-chrome >/dev/null 2>&1; then
    google-chrome --disable-web-security --user-data-dir="${BROWSER_PROFILE}" --disable-features=VizDisplayCompositor "${url}" &
  else
    echo "⚠️ Chrome not found. Please open ${url} manually."
  fi
}

cleanup() {
  if [[ -n "${SERVER_PID:-}" ]] && ps -p "${SERVER_PID}" >/dev/null 2>&1; then
    kill "${SERVER_PID}" || true
  fi
}

echo "🔧 Running Development..."
kill_port "${PORT}"
set_env_dev
build_web
copy_x_app_sdk
compress_assets_for_dev
start_server
trap cleanup EXIT INT TERM
sleep 2
open_browser
wait "${SERVER_PID}"
