#!/bin/bash

# Terminal colors
BOLD="\033[1m"
GREEN="\033[0;32m"
BLUE="\033[0;34m"
YELLOW="\033[0;33m"
RED="\033[0;31m"
RESET="\033[0m"
CYAN="\033[0;36m"
PURPLE="\033[0;35m"

# Check for required dependencies
check_dependencies() {
  local missing_deps=()
  
  echo -e "${BOLD}Checking dependencies...${RESET}"
  
  # Check for ffmpeg
  if ! command -v ffmpeg &> /dev/null; then
    missing_deps+=("ffmpeg")
  fi
  
  # Check for jq
  if ! command -v jq &> /dev/null; then
    missing_deps+=("jq")
  fi
  
  # Check for curl
  if ! command -v curl &> /dev/null; then
    missing_deps+=("curl")
  fi
  
  # Check for bc (for calculations)
  if ! command -v bc &> /dev/null; then
    missing_deps+=("bc")
  fi
  
  # If there are missing dependencies, show instructions and exit
  if [ ${#missing_deps[@]} -ne 0 ]; then
    echo -e "\n${BOLD}${RED}Error:${RESET} Missing required dependencies."
    echo -e "${BOLD}Please install the following:${RESET}"
    
    for dep in "${missing_deps[@]}"; do
      echo -e "  ${YELLOW}•${RESET} ${dep}"
    done
    
    echo -e "\n${BOLD}For installation instructions, please visit:${RESET}"
    echo -e "  ${CYAN}https://voice-api.app/docs/tools/subtitlepro/requirements${RESET}"
    exit 1
  else
    echo -e "${GREEN}✓${RESET} All dependencies are installed.\n"
  fi
}

# Run dependency check
check_dependencies

# Check for input file
if [ -z "$1" ]; then
  echo -e "${BOLD}${RED}Error:${RESET} No input file provided."
  echo -e "${BOLD}Usage:${RESET} $0 <movie_file_path>"
  exit 1
fi

MOVIE_FILE="$1"
TEMP_DIR=$(mktemp -d)
API_URL="https://voice-api.app/api/v1/public/audio/upload"
RESULTS_URL="https://voice-api.app/api/v1/public/audio/transcribing"
API_KEY="your-actual-api-key"

FILE_BASE_NAME=$(basename "$MOVIE_FILE")

# Show welcome banner
echo -e "\n${BOLD}${BLUE}======================================================${RESET}"
echo -e "${BOLD}${BLUE}          🎬 Subtitle Pro - voice-api.app          ${RESET}"
echo -e "${BOLD}${BLUE}======================================================${RESET}\n"

echo -e "${BOLD}Processing:${RESET} ${CYAN}${FILE_BASE_NAME}${RESET}\n"

# Function to show a spinner during long operations
spinner() {
  local pid=$1
  local delay=0.1
  local spinstr='|/-\'
  while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do
    local temp=${spinstr#?}
    printf " [%c]  " "$spinstr"
    local spinstr=$temp${spinstr%"$temp"}
    sleep $delay
    printf "\b\b\b\b\b\b"
  done
  printf "    \b\b\b\b"
}

# Function to detect language from audio track name
detect_language() {
  local track_description="$1"
  local language="unknown"
  
  # Convert description to lowercase for case-insensitive matching
  local desc_lower=$(echo "$track_description" | tr '[:upper:]' '[:lower:]')
  
  # Define language mapping as associative arrays, organized by individual languages
  declare -A lang_codes
  
  # English
  lang_codes+=(
    ["english"]="en"
    ["eng"]="en"
  )
  
  # German
  lang_codes+=(
    ["german"]="de"
    ["ger"]="de"
    ["deu"]="de"
  )
  
  # French
  lang_codes+=(
    ["french"]="fr"
    ["fre"]="fr"
    ["fra"]="fr"
  )
  
  # Spanish
  lang_codes+=(
    ["spanish"]="es"
    ["spa"]="es"
  )
  
  # Italian
  lang_codes+=(
    ["italian"]="it"
    ["ita"]="it"
  )
  
  # Dutch
  lang_codes+=(
    ["dutch"]="nl"
    ["dut"]="nl"
    ["nld"]="nl"
  )
  
  # Portuguese
  lang_codes+=(
    ["portuguese"]="pt"
    ["por"]="pt"
  )
  
  # Russian
  lang_codes+=(
    ["russian"]="ru"
    ["rus"]="ru"
  )
  
  # Polish
  lang_codes+=(
    ["polish"]="pl"
    ["pol"]="pl"
  )
  
  # Czech
  lang_codes+=(
    ["czech"]="cs"
    ["cze"]="cs"
    ["ces"]="cs"
  )
  
  # Swedish
  lang_codes+=(
    ["swedish"]="sv"
    ["swe"]="sv"
  )
  
  # Norwegian
  lang_codes+=(
    ["norwegian"]="no"
    ["nor"]="no"
  )
  
  # Danish
  lang_codes+=(
    ["danish"]="da"
    ["dan"]="da"
  )
  
  # Finnish
  lang_codes+=(
    ["finnish"]="fi"
    ["fin"]="fi"
  )
  
  # Greek
  lang_codes+=(
    ["greek"]="el"
    ["gre"]="el"
    ["ell"]="el"
  )
  
  # Hungarian
  lang_codes+=(
    ["hungarian"]="hu"
    ["hun"]="hu"
  )
  
  # Turkish
  lang_codes+=(
    ["turkish"]="tr"
    ["tur"]="tr"
  )
  
  # Check if any language identifier is in the description
  for lang_identifier in "${!lang_codes[@]}"; do
    if [[ "$desc_lower" == *"$lang_identifier"* ]]; then
      language="${lang_codes[$lang_identifier]}"
      break
    fi
  done
  
  echo "$language"
}

# Function to get full language name from code
get_language_name() {
  local code=$1
  case $code in
    "en") echo "English" ;;
    "de") echo "German" ;;
    "fr") echo "French" ;;
    "es") echo "Spanish" ;;
    "it") echo "Italian" ;;
    "nl") echo "Dutch" ;;
    "pt") echo "Portuguese" ;;
    "ru") echo "Russian" ;;
    "pl") echo "Polish" ;;
    "cs") echo "Czech" ;;
    "sv") echo "Swedish" ;;
    "no") echo "Norwegian" ;;
    "da") echo "Danish" ;;
    "fi") echo "Finnish" ;;
    "el") echo "Greek" ;;
    "hu") echo "Hungarian" ;;
    "tr") echo "Turkish" ;;
    *) echo "Unknown" ;;
  esac
}

# Function to handle API errors and subscription issues
handle_api_error() {
  local response="$1"
  local http_code="$2"
  
  echo -e "\n${BOLD}${RED}Error:${RESET} API request failed."
  
  # Try to extract error message safely without causing jq errors
  local error_message=""
  local error_code=""
  
  # Check if response is likely to be JSON
  if [[ "$response" == *"{"* && "$response" == *"}"* ]]; then
    # Try to parse as JSON, but handle errors gracefully
    error_message=$(echo "$response" | jq -r '. | if type=="object" then .message // "" else . end' 2>/dev/null)
    error_code=$(echo "$response" | jq -r '.code // ""' 2>/dev/null)
    
    # If jq failed or returned null/empty
    if [ $? -ne 0 ] || [ -z "$error_message" ]; then
      # Try to show the raw response instead
      error_message=$(echo "$response" | tr -d '\r\n' | sed 's/^.*message":"*\([^"]*\)".*$/\1/' 2>/dev/null)
    fi
  else
    # Not JSON, just show as plain text
    error_message="$response"
  fi
  
  # If we still have no error message
  if [ -z "$error_message" ]; then
    error_message="No error details available"
  fi
  
  case "$http_code" in
     401) # UNAUTHORIZED
      if [[ "$error_message" == *"Subscription not found"* ]]; then
        echo -e "${BOLD}Subscription Error:${RESET} ${YELLOW}Subscription not found for your API key.${RESET}"
        echo -e "Please check your API key or sign up for a subscription at ${CYAN}https://voice-api.app/signup${RESET}"
      elif [[ "$error_message" == *"Api key not present"* ]] || [[ "$error_message" == *"invalid"* ]]; then
        echo -e "${BOLD}Authentication Error:${RESET} ${YELLOW}Invalid or missing API key.${RESET}"
        echo -e "Please check your API key and make sure it's correct."
        echo -e "You can find your API key in your account dashboard at ${CYAN}https://voice-api.app/dashboard${RESET}"
      else
        echo -e "${BOLD}Authentication Error:${RESET}"
        echo -e "Please check your API key or account status at ${CYAN}https://voice-api.app/dashboard${RESET}"
      fi
      ;;
    
    403) # FORBIDDEN
      if [[ "$error_message" == *"Rate limit exceeded"* ]] || [[ "$error_message" == *"limit"* ]]; then
        echo -e "${BOLD}Quota Exceeded:${RESET} ${YELLOW}You have used all your available transcription minutes.${RESET}"
        echo -e "Please upgrade your plan or wait until your quota resets."
        echo -e "Visit ${CYAN}https://voice-api.app/dashboard${RESET} to manage your subscription."
      elif [[ "$error_message" == *"Subscription not active"* ]] || [[ "$error_message" == *"expired"* ]]; then
        echo -e "${BOLD}Subscription Error:${RESET} ${YELLOW}Your subscription is not active or has expired.${RESET}"
        echo -e "Please renew your subscription at ${CYAN}https://voice-api.app/dashboard${RESET}"
      else
        echo -e "${BOLD}Access Denied:${RESET}"
        echo -e "If you believe this is an error, please contact ${CYAN}support@voice-api.app${RESET}"
      fi
      ;;
    
    402) # PAYMENT REQUIRED
      echo -e "${BOLD}Subscription Error:${RESET} ${YELLOW}Payment required.${RESET}"
      echo -e "Your subscription may need to be renewed or a payment issue needs to be resolved."
      echo -e "Please visit ${CYAN}https://voice-api.app/dashboard${RESET} to manage your subscription."
      ;;
    
    404) # NOT FOUND
      echo -e "${BOLD}Not Found:${RESET} ${YELLOW}$error_message${RESET}"
      echo -e "The requested resource or endpoint could not be found."
      ;;
    
    429) # TOO MANY REQUESTS
      echo -e "${BOLD}Rate Limited:${RESET} ${YELLOW}Too many requests.${RESET}"
      echo -e "Please try again later or upgrade your subscription for higher limits."
      ;;
    
    5*) # SERVER ERRORS
      echo -e "${BOLD}Server Error:${RESET} ${YELLOW}The service is experiencing issues.${RESET}"
      echo -e "Error details: $error_message"
      echo -e "Please try again later or contact support at ${CYAN}support@voice-api.app${RESET}"
      ;;
    
    *)
      echo -e "${BOLD}Error Details:${RESET} ${YELLOW}$error_message${RESET}"
      echo -e "If this issue persists, please contact support at ${CYAN}support@voice-api.app${RESET}"
      ;;
  esac
  
  # If we have detailed error information, show it at the end
  if [ ! -z "$error_message" ] && [ "$error_message" != "null" ] && [ "$error_message" != "No error details available" ]; then
    echo -e "\n${BOLD}Details:${RESET} ${YELLOW}$error_message${RESET}"
  fi
  
  # Clean up temporary files before exiting
  echo -e "\n${CYAN}•${RESET} Cleaning up temporary files..."
  rm -rf "$TEMP_DIR"
  exit 1
}

# Step 1: Show available audio tracks
echo -e "${BOLD}${BLUE}[1/5]${RESET} ${BOLD}Detecting audio tracks...${RESET}"
AUDIO_TRACKS_OUTPUT=$(ffmpeg -i "$MOVIE_FILE" 2>&1 | grep "Stream #" | grep "Audio")

if [ -z "$AUDIO_TRACKS_OUTPUT" ]; then
  echo -e "${BOLD}${RED}Error:${RESET} No audio tracks found in the file."
  exit 1
fi

echo -e "\n${BOLD}Available audio tracks:${RESET}"
echo -e "${CYAN}---------------------------------------${RESET}"
echo "$AUDIO_TRACKS_OUTPUT" | nl | while read -r line; do
  track_num=$(echo "$line" | awk '{print $1}')
  track_info=$(echo "$line" | cut -d' ' -f2-)
  track_desc=$(detect_language "$track_info")
  lang_name=$(get_language_name "$track_desc")
  
  # Extract language code from the track info if available
  lang_code=$(echo "$track_info" | grep -o -E '\([a-z]{3}\)' | tr -d '()')
  
  if [ "$track_desc" != "unknown" ]; then
    echo -e " ${BOLD}$track_num.${RESET} $track_info ${YELLOW}[Detected: $lang_name]${RESET}"
  else
    echo -e " ${BOLD}$track_num.${RESET} $track_info"
  fi
done
echo -e "${CYAN}---------------------------------------${RESET}"

# Ask the user to select an audio track
echo -e "\n${BOLD}Please select the audio track number to transcribe:${RESET}"
read -r AUDIO_TRACK_NUMBER

if ! [[ "$AUDIO_TRACK_NUMBER" =~ ^[0-9]+$ ]]; then
  echo -e "${BOLD}${RED}Error:${RESET} Invalid selection. Please enter a valid track number."
  exit 1
fi

# Get the selected track description for language detection
SELECTED_TRACK_DESC=$(echo "$AUDIO_TRACKS_OUTPUT" | sed -n "${AUDIO_TRACK_NUMBER}p")
DETECTED_LANGUAGE=$(detect_language "$SELECTED_TRACK_DESC")
LANGUAGE_NAME=$(get_language_name "$DETECTED_LANGUAGE")

echo -e "\n${BOLD}Selected:${RESET} Track $AUDIO_TRACK_NUMBER"
echo -e "${BOLD}Language:${RESET} ${YELLOW}$LANGUAGE_NAME${RESET} (${PURPLE}$DETECTED_LANGUAGE${RESET})\n"

AUDIO_TRACK_INDEX=$((AUDIO_TRACK_NUMBER))
SELECTED_AUDIO="$TEMP_DIR/selected_audio.wav"

# Step 2: Extract and re-encode the selected audio track
echo -e "${BOLD}${BLUE}[2/5]${RESET} ${BOLD}Extracting audio...${RESET}"
echo -ne "  ${CYAN}•${RESET} Processing... "
ffmpeg -i "$MOVIE_FILE" -map 0:$AUDIO_TRACK_INDEX -c:a pcm_s16le -ar 16000 -ac 1 "$SELECTED_AUDIO" -loglevel error || {
  echo -e "\n${BOLD}${RED}Error:${RESET} Failed to extract and re-encode the selected audio track."
  exit 1
}
echo -e "${GREEN}Done!${RESET}"

# Step 3: Upload audio to transcription service
echo -e "\n${BOLD}${BLUE}[3/5]${RESET} ${BOLD}Uploading to voice-api.app...${RESET}"
echo -ne "  ${CYAN}•${RESET} Uploading... "

# Use curl with -i flag to include headers in response and capture HTTP status code
HTTP_RESPONSE=$(curl -s -w "HTTPSTATUS:%{http_code}" -i --location \
  --form "file=@$SELECTED_AUDIO" \
  "$API_URL?api_key=$API_KEY&language=$DETECTED_LANGUAGE")

# Extract status code
HTTP_STATUS=$(echo "$HTTP_RESPONSE" | tr -d '\r' | sed -n -e 's/.*HTTPSTATUS://p')

# Extract headers and body
HEADERS=$(echo "$HTTP_RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g' | awk 'BEGIN{RS="\r\n\r\n";ORS="\n\n"} {print $0; exit}')
UPLOAD_RESPONSE=$(echo "$HTTP_RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g' | awk 'BEGIN{RS="\r\n\r\n";ORS="\n\n"} {if(NR==2) print $0}')

# Check if the request was successful
if [ ! "$HTTP_STATUS" -eq 200 ]; then
  echo -e "${RED}Failed!${RESET}"
  handle_api_error "$UPLOAD_RESPONSE" "$HTTP_STATUS"
fi

# Extract quota information from headers
QUOTA_LIMIT=$(echo "$HEADERS" | grep -i "x-quotas-limit" | cut -d ':' -f 2 | tr -d ' \r')
QUOTA_REMAINING=$(echo "$HEADERS" | grep -i "x-quotas-remaining" | cut -d ':' -f 2 | tr -d ' \r')
QUOTA_RENEWAL=$(echo "$HEADERS" | grep -i "x-quotas-renewal-date" | cut -d ':' -f 2- | tr -d '\r')

# Extract jobId from response
JOB_ID=$(echo "$UPLOAD_RESPONSE" | jq -r '.data.jobId')

if [ -z "$JOB_ID" ] || [ "$JOB_ID" == "null" ]; then
  echo -e "${RED}Failed!${RESET}"
  echo -e "\n${BOLD}${RED}Error:${RESET} Failed to retrieve jobId from transcription service."
  echo -e "${RED}Response:${RESET} $UPLOAD_RESPONSE"
  rm -rf "$TEMP_DIR"
  exit 1
fi
echo -e "${GREEN}Done!${RESET}"

echo -e "  ${CYAN}•${RESET} Job ID: ${PURPLE}$JOB_ID${RESET}"

# Display remaining minutes if available
if [ ! -z "$QUOTA_REMAINING" ] && [ ! -z "$QUOTA_LIMIT" ]; then
  QUOTA_REMAINING_MIN=$(echo "scale=1; $QUOTA_REMAINING/60" | bc)
  echo -e "  ${CYAN}•${RESET} Remaining credits: ${YELLOW}${QUOTA_REMAINING_MIN}${RESET} minutes"
fi

# Step 4: Poll for transcription results
echo -e "\n${BOLD}${BLUE}[4/5]${RESET} ${BOLD}Processing transcription...${RESET}"
echo -e "  ${CYAN}•${RESET} This may take a while, depending on the file length."

counter=0
start_time=$(date +%s)
while true; do
  # Show progress indicator
  counter=$((counter + 1))
  case $((counter % 4)) in
    0) progress="⣿";;
    1) progress="⣾";;
    2) progress="⣷";;
    3) progress="⣽";;
  esac
  
  # Calculate elapsed time
  current_time=$(date +%s)
  elapsed=$((current_time - start_time))
  minutes=$((elapsed / 60))
  seconds=$((elapsed % 60))
  
  # Update progress message
  echo -ne "  ${YELLOW}$progress${RESET} Processing... (${minutes}m ${seconds}s elapsed)\r"
  
  # Make request and capture HTTP status code
  HTTP_RESPONSE=$(curl -s -w "HTTPSTATUS:%{http_code}" --location \
    "$RESULTS_URL/$JOB_ID?api_key=$API_KEY&format=srt")
    
  # Extract status code
  HTTP_STATUS=$(echo "$HTTP_RESPONSE" | tr -d '\r' | sed -n -e 's/.*HTTPSTATUS://p')
  
  # Extract response body
  RESPONSE=$(echo "$HTTP_RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
  
  # Check if the request was successful
  if [ ! "$HTTP_STATUS" -eq 200 ]; then
    echo -e "\n${BOLD}${RED}Error:${RESET} Failed to check transcription status."
    handle_api_error "$RESPONSE" "$HTTP_STATUS"
  fi

  STATUS=$(echo "$RESPONSE" | jq -r '.data.status')

  if [ "$STATUS" == "COMPLETED" ]; then
    echo -e "  ${GREEN}✓${RESET} Transcription completed!                      "
    break
  fi

  if [ "$STATUS" == "FAILED" ]; then
    echo -e "\n${BOLD}${RED}Error:${RESET} Transcription failed."
    echo -e "${RED}Response:${RESET} $RESPONSE"
    rm -rf "$TEMP_DIR"
    exit 1
  fi

  sleep 5
done

# Step 5: Save transcription results
echo -e "\n${BOLD}${BLUE}[5/5]${RESET} ${BOLD}Saving subtitles...${RESET}"
TRANSCRIBING_RESULTS=$(echo "$RESPONSE" | jq -r '.data.transcribingResults')

if [ -z "$TRANSCRIBING_RESULTS" ]; then
  echo -e "${BOLD}${RED}Error:${RESET} Failed to retrieve transcription results."
  exit 1
fi

# Use detected language for the subtitle file name
SUBTITLE_FILE="${MOVIE_FILE%.*}.voice-api.app.$DETECTED_LANGUAGE.srt"

echo -e "  ${CYAN}•${RESET} Saving to: ${YELLOW}$(basename "$SUBTITLE_FILE")${RESET}"
echo "$TRANSCRIBING_RESULTS" > "$SUBTITLE_FILE"

# Clean up temporary files
echo -e "  ${CYAN}•${RESET} Cleaning up temporary files..."
rm -rf "$TEMP_DIR"

# Format the quota renewal date to make it more readable
if [ ! -z "$QUOTA_RENEWAL" ]; then
  # Try to convert ISO date to a more human-readable format
  if command -v date &> /dev/null; then
    # Extract just the date part for better formatting
    RENEWAL_DATE_FORMATTED=$(echo "$QUOTA_RENEWAL" | cut -dT -f1)
    # Try to parse with date command if available
    if date -d "$RENEWAL_DATE_FORMATTED" &> /dev/null; then
      RENEWAL_DATE_FORMATTED=$(date -d "$RENEWAL_DATE_FORMATTED" "+%B %d, %Y")
    fi
  else
    RENEWAL_DATE_FORMATTED=$QUOTA_RENEWAL
  fi
fi



# Show completion message
echo -e "\n${BOLD}${GREEN}✓ Success!${RESET} ${BOLD}Subtitles created.${RESET}"
echo -e "  ${BOLD}Language:${RESET} $LANGUAGE_NAME ($DETECTED_LANGUAGE)"
echo -e "  ${BOLD}File:${RESET} ${YELLOW}$(basename "$SUBTITLE_FILE")${RESET}"
echo -e "  ${BOLD}Location:${RESET} ${CYAN}$(dirname "$SUBTITLE_FILE")${RESET}"



# Calculate minutes from seconds for better readability
QUOTA_LIMIT_MIN=0
QUOTA_REMAINING_MIN=0
if [ ! -z "$QUOTA_LIMIT" ]; then
  QUOTA_LIMIT_MIN=$(echo "scale=1; $QUOTA_LIMIT/60" | bc)
fi
if [ ! -z "$QUOTA_REMAINING" ]; then
  QUOTA_REMAINING_MIN=$(echo "scale=1; $QUOTA_REMAINING/60" | bc)

  # Add warning if quota is getting low (less than 10% remaining)
  QUOTA_THRESHOLD=$(echo "$QUOTA_LIMIT * 0.1" | bc)
  if (( $(echo "$QUOTA_REMAINING < $QUOTA_THRESHOLD" | bc -l) )); then
    echo -e "\n${BOLD}${YELLOW}Warning:${RESET} Your subscription credits are running low."
    echo -e "You have ${YELLOW}${QUOTA_REMAINING_MIN}${RESET} minutes remaining out of ${QUOTA_LIMIT_MIN}."
    echo -e "Consider upgrading your plan at ${CYAN}https://voice-api.app${RESET}"
  fi
fi

# Show subscription information if available
if [ ! -z "$QUOTA_LIMIT" ] && [ ! -z "$QUOTA_REMAINING" ] && [ ! -z "$QUOTA_RENEWAL" ]; then
  echo -e "\n${BOLD}${BLUE}Subscription Information:${RESET}"
  echo -e "  ${BOLD}Total Credits:${RESET} ${YELLOW}${QUOTA_LIMIT_MIN}${RESET} minutes"
  echo -e "  ${BOLD}Remaining:${RESET} ${YELLOW}${QUOTA_REMAINING_MIN}${RESET} minutes (current transcription not deducted yet)"
  echo -e "  ${BOLD}Next Renewal:${RESET} ${CYAN}${RENEWAL_DATE_FORMATTED}${RESET}"
fi

echo -e "\n${BOLD}${BLUE}======================================================${RESET}"
echo -e "${BOLD}${BLUE}          Thank you for using Subtitle Pro!          ${RESET}"
echo -e "${BOLD}${BLUE}======================================================${RESET}\n"
