#!/bin/bash
set -euo pipefail
FONT_COLOR="#3C3C3C"                # color for light text
FONT_BOLD_COLOR="#B51700"           # color for bold text

ONLY_IPHONE=false
ONLY_IPAD=false

usage() {
  cat <<'EOF'
Usage: frame_screens.sh [--iphone-only|--ipad-only] [SRC_ROOT] [BG_IMAGE] [OUT_ROOT]

  --iphone-only   Only frame screenshots whose device slug is not iPad.
  --ipad-only     Only frame screenshots whose device slug contains iPad.
  SRC_ROOT        Root folder with device/lang subfolders (default: Shots/Screenshots)
  BG_IMAGE        Background image to use (default: Shots/frame-bg.png)
  OUT_ROOT        Output folder for framed shots (default: Shots/Framed)
EOF
}

POSITIONAL_ARGS=()
while [[ $# -gt 0 ]]; do
  case "$1" in
    --iphone-only)
      ONLY_IPHONE=true
      shift
      ;;
    --ipad-only)
      ONLY_IPAD=true
      shift
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    --)
      shift
      POSITIONAL_ARGS+=("$@")
      break
      ;;
    -*)
      echo "Unknown option: $1" >&2
      usage >&2
      exit 1
      ;;
    *)
      POSITIONAL_ARGS+=("$1")
      shift
      ;;
  esac
done

if [[ "$ONLY_IPHONE" == true && "$ONLY_IPAD" == true ]]; then
  echo "Cannot use --iphone-only and --ipad-only together." >&2
  exit 1
fi

if ((${#POSITIONAL_ARGS[@]})); then
  set -- "${POSITIONAL_ARGS[@]}"
else
  set --
fi

# Inputs
SRC_ROOT="${1:-Shots/Screenshots}"       # root folder with device/lang subfolders (iphone-17-pro-max/en/, ipad-pro-13-inch-m4/de/…)
BG_IMAGE="${2:-Shots/frame-bg-phone.png}" # default background image for iPhone shots
OUT_ROOT="${3:-Shots/Framed}"            # output folder
FONT="./Shots/Fonts/Oswald-Light.ttf"  # font for title text
FONT_BOLD="./Shots/Fonts/Oswald-SemiBold.ttf"  # font for *emphasized* text
TITLE_POINTSIZE="${TITLE_POINTSIZE:-148}"      # baseline point size for titles

# Tweakables
CORNER_RADIUS="auto"              # corner radius; "auto" picks a good value based on width
INSET=2                            # inset (px) to shave off simulator’s black edge pixels
SHADOW_OPACITY=0                  # 0–100
SHADOW_BLUR=20                     # blur radius
SHADOW_OFFSET_X=0                  # px
SHADOW_OFFSET_Y=40                 # px
CANVAS_MARGIN=245                  # default margin around the device on the background, px
TITLE_MARGIN=378                   # default margin above the device for title text, px
TITLE_LINE_SPACING=220             # vertical distance between lines of the title text, px
START_FRAME_IMAGE="${START_FRAME_IMAGE:-Shots/frame-start-iphone.png}"    # static framed asset for the intro screen
START_FRAME_FILENAME="${START_FRAME_FILENAME:-00-StartFrameTitle.png}"   # output filename for the intro screen
START_FRAME_TITLE_KEY="${START_FRAME_TITLE_KEY:-StartFrameTitle}"        # key in the localization files
START_FRAME_TITLE_Y="${START_FRAME_TITLE_Y:-$((TITLE_MARGIN - 100))}"    # Y offset for the intro title text
START_FRAME_POINTSIZE="${START_FRAME_POINTSIZE:-$TITLE_POINTSIZE}"       # point size for intro title (defaults to standard)
START_FRAME_RESIZE="${START_FRAME_RESIZE:-true}"                         # resize intro frame to target dimensions

# Device-specific overrides (can be tuned via env vars)
TARGET_WIDTH_PHONE="${TARGET_WIDTH_PHONE:-1320}"
TARGET_HEIGHT_PHONE="${TARGET_HEIGHT_PHONE:-2868}"
TARGET_WIDTH_IPAD="${TARGET_WIDTH_IPAD:-2048}"
TARGET_HEIGHT_IPAD="${TARGET_HEIGHT_IPAD:-2732}"
IPAD_BG_IMAGE="${IPAD_BG_IMAGE:-Shots/frame-bg.png}"
IPAD_CANVAS_MARGIN="${IPAD_CANVAS_MARGIN:-240}"
IPAD_TITLE_MARGIN="${IPAD_TITLE_MARGIN:-180}"
IPAD_FRAME_WIDTH="${IPAD_FRAME_WIDTH:-2200}"
IPAD_FRAME_TOP_OFFSET="${IPAD_FRAME_TOP_OFFSET:-572}"
IPAD_CORNER_RADIUS="${IPAD_CORNER_RADIUS:-60}"

mkdir -p "$OUT_ROOT"

# Function to render mixed-font text (light + semi-bold for *text*)
render_mixed_font_title() {
  local canvas="$1"
  local title_text="$2"
  local title_y="$3"
  local output="$4"
  local point_size="${5:-$TITLE_POINTSIZE}"
  local line_spacing="${6:-$TITLE_LINE_SPACING}"

  local expanded_title
  expanded_title="$(printf '%b' "$title_text")"

  local temp_img
  temp_img="$(mktemp /tmp/text_temp.XXXXXX_$$.png)"
  cp "$canvas" "$temp_img"

  read -r canvas_w canvas_h <<<"$(identify -format "%w %h" "$canvas")"

  local -a lines=()
  while IFS= read -r line || [[ -n "$line" ]]; do
    lines+=("$line")
  done < <(printf '%s' "$expanded_title")

  if ((${#lines[@]} == 0)); then
    lines+=("$expanded_title")
  fi

  if ((${#lines[@]} > 2)); then
    lines=("${lines[@]:0:2}")
  fi

  for idx in "${!lines[@]}"; do
    local line="${lines[$idx]}"
    local current_y=$((title_y + idx * line_spacing))

    local -a text_segments=()
    local -a font_types=()
    local current_text=""
    local in_bold=false
    local i=0
    local line_length=${#line}

    while [ $i -lt $line_length ]; do
      local char="${line:$i:1}"
      if [[ "$char" == "*" ]]; then
        text_segments+=("$current_text")
        if [[ "$in_bold" == true ]]; then
          font_types+=("bold")
        else
          font_types+=("light")
        fi
        current_text=""
        if [[ "$in_bold" == true ]]; then
          in_bold=false
        else
          in_bold=true
        fi
      else
        current_text+="$char"
      fi
      i=$((i + 1))
    done

    text_segments+=("$current_text")
    if [[ "$in_bold" == true ]]; then
      font_types+=("bold")
    else
      font_types+=("light")
    fi

    local total_width=0
    for ((j = 0; j < ${#text_segments[@]}; j++)); do
      local segment="${text_segments[$j]}"
      if [[ -n "$segment" ]]; then
        local font_for_measurement="$FONT"
        if [[ "${font_types[$j]}" == "bold" ]]; then
          font_for_measurement="$FONT_BOLD"
        fi
        local segment_for_measurement="$segment"
        segment_for_measurement="${segment_for_measurement/#/ }"
        segment_for_measurement="${segment_for_measurement/%/ }"
        local part_width
        part_width=$(magick -font "$font_for_measurement" -pointsize "$point_size" -size x label:"$segment_for_measurement" -format "%w" info:)
        total_width=$((total_width + part_width))
      fi
    done

    if (( total_width <= 0 )); then
      continue
    fi

    local start_x=$(( (canvas_w - total_width) / 2 ))
    local x_offset=0
    for ((j = 0; j < ${#text_segments[@]}; j++)); do
      local segment="${text_segments[$j]}"
      if [[ -n "$segment" ]]; then
        local font_to_use="$FONT"
        local color_to_use="$FONT_COLOR"
        if [[ "${font_types[$j]}" == "bold" ]]; then
          font_to_use="$FONT_BOLD"
          color_to_use="$FONT_BOLD_COLOR"
        fi
        local segment_for_rendering="$segment"
        segment_for_rendering="${segment_for_rendering/#/ }"
        segment_for_rendering="${segment_for_rendering/%/ }"
        magick "$temp_img" \
          -font "$font_to_use" -pointsize "$point_size" -fill "$color_to_use" \
          -gravity northwest -annotate "+$((start_x + x_offset))+${current_y}" "$segment_for_rendering" \
          "$temp_img"
        local text_width
        text_width=$(magick -font "$font_to_use" -pointsize "$point_size" -size x label:"$segment_for_rendering" -format "%w" info:)
        x_offset=$((x_offset + text_width))
      fi
    done
  done

  cp "$temp_img" "$output"
  rm -f "$temp_img"
}

# Function to get title from config file
get_title() {
  local lang="$1"
  local screenshot_name="$2"
  local config_file="./Shots/Titles/${lang}.conf"
  
  # Extract view name from filename format: 03-LoadEditorView_0_5EE662BD-84C7-41AC-806E-EB8C7340A037.png
  # Remove .png extension, then extract the part after the first dash and before the first underscore
  local base_name=$(basename "$screenshot_name" .png)
  # Remove leading number and dash (e.g., "03-")
  base_name=${base_name#*-}
  # Remove everything from the first underscore onwards (e.g., "_0_5EE662BD...")
  base_name=${base_name%%_*}
  
  # Try to find title in config file
  if [[ -f "$config_file" ]]; then
    local title=$(grep "^${base_name}=" "$config_file" 2>/dev/null | cut -d'=' -f2-)
    if [[ -n "$title" ]]; then
      echo "$title"
      return
    fi
  fi
  
  # Fallback to default title
  echo "***NOT SET***"
}

should_render_start_frame() {
  local device_slug="$1"

  if [[ ! -f "$START_FRAME_IMAGE" ]]; then
    return 1
  fi

  if [[ -z "$device_slug" ]]; then
    return 1
  fi

  local slug_lower
  slug_lower="$(printf '%s' "$device_slug" | tr '[:upper:]' '[:lower:]')"
  if [[ "$slug_lower" == *"iphone"* ]]; then
    return 0
  fi

  return 1
}

render_start_frame_for_lang() {
  local output_dir="$1"
  local lang="$2"
  local log_prefix="$3"
  local target_width="$4"
  local target_height="$5"
  local canvas_margin="$6"
  local title_margin="$7"

  if [[ ! -f "$START_FRAME_IMAGE" ]]; then
    return 0
  fi

  local title_text
  title_text="$(get_title "$lang" "$START_FRAME_TITLE_KEY")"
  if [[ -z "$title_text" || "$title_text" == "***NOT SET***" ]]; then
    echo "Skipped start frame (no title): ${log_prefix}/${START_FRAME_FILENAME}"
    return 0
  fi

  mkdir -p "$output_dir"
  local dest="$output_dir/$START_FRAME_FILENAME"
  rm -f "$dest"
  local resize_flag
  resize_flag="$(printf '%s' "$START_FRAME_RESIZE" | tr '[:upper:]' '[:lower:]')"

  local working_canvas
  working_canvas="$(mktemp /tmp/start_frame_canvas.XXXXXX_$$.png)"
  if [[ "$resize_flag" == "true" && -n "${target_width:-}" && -n "${target_height:-}" ]]; then
    magick "$START_FRAME_IMAGE" -resize "${target_width}x${target_height}^" -gravity center -extent "${target_width}x${target_height}" "$working_canvas"
  else
    cp "$START_FRAME_IMAGE" "$working_canvas"
  fi

  local point_size="$START_FRAME_POINTSIZE"
  local scaled_title_y="$START_FRAME_TITLE_Y"
  local scaled_line_spacing="$TITLE_LINE_SPACING"
  if [[ -n "${target_height:-}" && -n "${canvas_margin:-}" && -n "${title_margin:-}" ]]; then
    local base_canvas_height=$(( target_height + 2 * canvas_margin + title_margin ))
    if (( base_canvas_height > 0 )); then
      read -r scaled_title_y scaled_line_spacing <<EOF
$(python3 - <<PY
target_height=${target_height}
base_canvas_height=${base_canvas_height}
title_y=${START_FRAME_TITLE_Y}
line_spacing=${TITLE_LINE_SPACING}
scale = target_height / base_canvas_height if base_canvas_height else 1
print(int(round(title_y * scale)), int(round(line_spacing * scale)))
PY
)
EOF
    fi
  fi
  if [[ -z "$scaled_title_y" || "$scaled_title_y" -lt 0 ]]; then
    scaled_title_y="$START_FRAME_TITLE_Y"
  fi
  if [[ -z "$scaled_line_spacing" || "$scaled_line_spacing" -le 0 ]]; then
    scaled_line_spacing="$TITLE_LINE_SPACING"
  fi

  render_mixed_font_title "$working_canvas" "$title_text" "$scaled_title_y" "$dest" "$point_size" "$scaled_line_spacing"
  rm -f "$working_canvas"
  if [[ -f "$dest" ]]; then
    echo "Start frame: $log_prefix/$START_FRAME_FILENAME"
  fi
}

# Function to frame one screenshot
frame_one () {
  local in="$1"            # input screenshot (e.g., 1320x2868)
  local out="$2"           # output image
  local bg="$3"
  local lang="$4"          # language code (e.g., "de", "en")
  local screenshot_name="$5"   # screenshot filename
  local target_width="$6"
  local target_height="$7"
  local canvas_margin="$8"
  local title_margin="$9"
  local frame_width="${10:-}"
  local frame_top_offset="${11:-}"
  local corner_radius_override="${12:-}"

  local title_text
  title_text="$(get_title "$lang" "$screenshot_name")"
  if [[ -z "$title_text" || "$title_text" == "***NOT SET***" ]]; then
    echo "Skipped (no title): ${lang}/${screenshot_name}"
    return 0
  fi

  # Read sizes
  read -r W H <<<"$(identify -format "%w %h" "$in")"

  # Determine corner radius
  local R
  if [[ -n "$corner_radius_override" ]]; then
    R="$corner_radius_override"
  elif [[ "$CORNER_RADIUS" == "auto" ]]; then
    # Heuristic: ~1/12 of width works well for iPhone 6.9" (≈110px for 1320px width)
    R=$(( W / 12 ))
  else
    R=$CORNER_RADIUS
  fi

  # Create rounded-corner mask the same size as the screenshot
  local mask
  mask="$(mktemp /tmp/mask.XXXXXX_$$.png)"
  magick -size "${W}x${H}" xc:black \
    -fill white -draw "roundrectangle ${INSET},${INSET},$((W-1-INSET)),$((H-1-INSET)),$R,$R" \
    "$mask"

  # Apply rounded corners + make a soft drop shadow
  # 1) Rounded PNG
  local rounded
  rounded="$(mktemp /tmp/rounded.XXXXXX_$$.png)"
  magick "$in" -alpha set "$mask" -compose copyopacity -composite "$rounded"
  if [[ -n "$frame_width" ]]; then
    magick "$rounded" -resize "${frame_width}x" "$rounded"
  fi

  # 2) Shadow from rounded image
  local shadow
  shadow="$(mktemp /tmp/shadow.XXXXXX_$$.png)"
  magick "$rounded" \
    \( +clone -background black -shadow ${SHADOW_OPACITY}x${SHADOW_BLUR}+${SHADOW_OFFSET_X}+${SHADOW_OFFSET_Y} \) \
    +swap -background none -layers merge +repage "$shadow"

  # Compose on the background, centered
  # First, scale background to be at least screenshot+margin in both dimensions
  read -r BW BH <<<"$(identify -format "%w %h" "$bg")"
  local minW=$((W + 2*canvas_margin))
  local minH=$((H + 2*canvas_margin + title_margin))
  local canvas
  canvas="$(mktemp /tmp/canvas.XXXXXX_$$.png)"
  magick "$bg" -resize "${minW}x${minH}^" -gravity center -extent "${minW}x${minH}" "$canvas"

  # Add title text above the screenshot
  local with_title
  with_title="$(mktemp /tmp/with_title.XXXXXX_$$.png)"
  
  # Calculate title position (center horizontally, positioned above the screenshot)
  local title_y=$((title_margin - 100))  # 10px from top of title margin
  
  # Render title with mixed fonts
  render_mixed_font_title "$canvas" "$title_text" "$title_y" "$with_title"

  # Now place shadow (which already includes the rounded image) positioned below the title
  # Calculate the vertical offset to center the screenshot in the remaining space below the title
  local screenshot_offset=$((title_margin*2))
  local placement_gravity="center"
  local placement_geometry="+0+${screenshot_offset}"
  if [[ -n "$frame_top_offset" ]]; then
    placement_gravity="north"
    placement_geometry="+0+${frame_top_offset}"
  fi
  local temp_result
  temp_result="$(mktemp /tmp/temp_result.XXXXXX_$$.png)"
  magick "$with_title" "$shadow" -gravity "$placement_gravity" -geometry "$placement_geometry" -compose over -composite "$temp_result"

  # Final step: scale to exact dimensions 1320 × 2868px
  magick "$temp_result" -resize "${target_width}x${target_height}^" -gravity center -extent "${target_width}x${target_height}" "$out"

  rm -f "$mask" "$rounded" "$shadow" "$canvas" "$with_title" "$temp_result"
}

# Process all screenshots in SRC_ROOT/*/*.png
resolve_device_profile() {
  local device_slug="$1"

  PROFILE_BG="$BG_IMAGE"
  PROFILE_TARGET_WIDTH="$TARGET_WIDTH_PHONE"
  PROFILE_TARGET_HEIGHT="$TARGET_HEIGHT_PHONE"
  PROFILE_CANVAS_MARGIN="$CANVAS_MARGIN"
  PROFILE_TITLE_MARGIN="$TITLE_MARGIN"
  PROFILE_FRAME_WIDTH=""
  PROFILE_FRAME_TOP_OFFSET=""
  PROFILE_CORNER_RADIUS=""

  if [[ -n "$device_slug" ]]; then
    local slug_lower
    slug_lower="$(printf '%s' "$device_slug" | tr '[:upper:]' '[:lower:]')"
    if [[ "$slug_lower" == *"ipad"* ]]; then
      PROFILE_BG="$IPAD_BG_IMAGE"
      PROFILE_TARGET_WIDTH="$TARGET_WIDTH_IPAD"
      PROFILE_TARGET_HEIGHT="$TARGET_HEIGHT_IPAD"
      PROFILE_CANVAS_MARGIN="$IPAD_CANVAS_MARGIN"
      PROFILE_TITLE_MARGIN="$IPAD_TITLE_MARGIN"
      PROFILE_FRAME_WIDTH="$IPAD_FRAME_WIDTH"
      PROFILE_FRAME_TOP_OFFSET="$IPAD_FRAME_TOP_OFFSET"
      PROFILE_CORNER_RADIUS="$IPAD_CORNER_RADIUS"
    fi
  fi
}

process_lang_dir() {
  local lang_path="$1"
  local lang="$2"
  local device_slug="$3"

  local out_dir="$OUT_ROOT"
  local log_prefix="$lang"

  if [[ -n "$device_slug" ]]; then
    out_dir="$out_dir/$device_slug"
    log_prefix="$device_slug/$lang"
  fi

  out_dir="$out_dir/$lang"
  mkdir -p "$out_dir"

  resolve_device_profile "$device_slug"

  shopt -s nullglob
  for shot in "$lang_path"/*.png; do
    local base="$(basename "$shot")"
    local dest="$out_dir/$base"
    rm -f "$dest"
    frame_one \
      "$shot" \
      "$dest" \
      "$PROFILE_BG" \
      "$lang" \
      "$base" \
      "$PROFILE_TARGET_WIDTH" \
      "$PROFILE_TARGET_HEIGHT" \
      "$PROFILE_CANVAS_MARGIN" \
      "$PROFILE_TITLE_MARGIN" \
      "$PROFILE_FRAME_WIDTH" \
      "$PROFILE_FRAME_TOP_OFFSET" \
      "$PROFILE_CORNER_RADIUS"
    if [[ -f "$dest" ]]; then
      echo "Framed: $log_prefix/$base"
    fi
  done

  if should_render_start_frame "$device_slug"; then
    render_start_frame_for_lang \
      "$out_dir" \
      "$lang" \
      "$log_prefix" \
      "$PROFILE_TARGET_WIDTH" \
      "$PROFILE_TARGET_HEIGHT" \
      "$PROFILE_CANVAS_MARGIN" \
      "$PROFILE_TITLE_MARGIN"
  fi
}

shopt -s nullglob
found_any=false
skipped_for_iphone_filter=false
skipped_for_ipad_filter=false
for entry in "$SRC_ROOT"/*; do
  [[ -d "$entry" ]] || continue
  entry_basename="$(basename "$entry")"
  entry_lower="$(printf '%s' "$entry_basename" | tr '[:upper:]' '[:lower:]')"
  is_ipad_entry=false
  if [[ "$entry_lower" == *"ipad"* ]]; then
    is_ipad_entry=true
  fi

  if [[ "$ONLY_IPHONE" == true && "$is_ipad_entry" == true ]]; then
    skipped_for_iphone_filter=true
    continue
  fi

  if [[ "$ONLY_IPAD" == true && "$is_ipad_entry" == false ]]; then
    skipped_for_ipad_filter=true
    continue
  fi

  pattern="${entry%/}/*.png"
  if compgen -G "$pattern" > /dev/null; then
    process_lang_dir "$entry" "$(basename "$entry")" ""
    found_any=true
    continue
  fi

  for langdir in "$entry"/*; do
    [[ -d "$langdir" ]] || continue
    if [[ "$ONLY_IPHONE" == true ]]; then
      lang_device_slug="$(basename "$entry")"
      lang_slug_lower="$(printf '%s' "$lang_device_slug" | tr '[:upper:]' '[:lower:]')"
      if [[ "$lang_slug_lower" == *"ipad"* ]]; then
        skipped_for_iphone_filter=true
        continue
      fi
    fi
    if [[ "$ONLY_IPAD" == true ]]; then
      lang_device_slug="$(basename "$entry")"
      lang_slug_lower="$(printf '%s' "$lang_device_slug" | tr '[:upper:]' '[:lower:]')"
      if [[ "$lang_slug_lower" != *"ipad"* ]]; then
        skipped_for_ipad_filter=true
        continue
      fi
    fi
    pattern="${langdir%/}/*.png"
    if compgen -G "$pattern" > /dev/null; then
      process_lang_dir "$langdir" "$(basename "$langdir")" "$(basename "$entry")"
      found_any=true
    fi
  done
done

if [[ "$found_any" == false ]]; then
  if [[ "$ONLY_IPHONE" == true ]]; then
    if [[ "$skipped_for_iphone_filter" == true ]]; then
      echo "No iPhone screenshots found under $SRC_ROOT" >&2
    else
      echo "No screenshots found under $SRC_ROOT" >&2
    fi
  elif [[ "$ONLY_IPAD" == true ]]; then
    if [[ "$skipped_for_ipad_filter" == true ]]; then
      echo "No iPad screenshots found under $SRC_ROOT" >&2
    else
      echo "No screenshots found under $SRC_ROOT" >&2
    fi
  else
    echo "No screenshots found under $SRC_ROOT" >&2
  fi
fi

echo "Done. Framed images in: $OUT_ROOT/"
