#!/bin/bash
# modules/interactive.sh - Interactive user interface functions

# Wait for user action with retry/skip/setup/exit options
function wait_for_user_action() {
  local error_message="$1"
  local fix_instructions="$2"
  local retry_function="$3"
  
  while true; do
    echo ""
    echo "${STATUS_STOP} $error_message"
    echo ""
    if [[ -n "$fix_instructions" ]]; then
      echo "${STATUS_CONFIG} To fix this:"
      echo "$fix_instructions"
      echo ""
    fi
    echo "${STATUS_INFO} After making the necessary changes, choose an action:"
    echo "   • Type 'retry' or 'r' to try again"
    echo "   • Type 'skip' or 's' to skip this step (if possible)"
    echo "   • Type 'setup' to restart interactive setup"
    echo "   • Type 'exit' or 'q' to quit"
    echo ""
    
    read -p "What would you like to do? [retry]: " user_action
    user_action="${user_action:-retry}"
    
    case "${user_action,,}" in
      "retry"|"r"|"")
        echo "${STATUS_RELOAD} Retrying..."
        if [[ -n "$retry_function" ]]; then
          if $retry_function; then
            print_success "Success! Continuing..."
            return 0
          fi
          # If retry failed, loop back to prompt again
        else
          return 0
        fi
        ;;
      "skip"|"s")
        echo "${STATUS_SKIP} Skipping this step..."
        return 1
        ;;
      "setup")
        echo "${STATUS_TARGET} Restarting interactive setup..."
        interactive_setup
        return 0
        ;;
      "exit"|"quit"|"q")
        echo "${STATUS_COMPLETE} Goodbye!"
        exit 0
        ;;
      *)
        print_error "Invalid option. Please try again."
        ;;
    esac
  done
}

# Prompt for a variable with validation
function prompt_for_variable() {
  local var_name="$1"
  local description="$2"
  local default_value="$3"
  local validation_pattern="$4"
  local user_input
  
  while true; do
    echo ""
    echo "${STATUS_INFO} $description"
    if [[ -n "$default_value" ]]; then
      read -p "Enter $var_name [$default_value]: " user_input
      user_input="${user_input:-$default_value}"
    else
      read -p "Enter $var_name: " user_input
    fi
    
    # Validate input if pattern provided
    if [[ -n "$validation_pattern" ]]; then
      if [[ ! $user_input =~ $validation_pattern ]]; then
        print_error "Invalid format. Please try again."
        continue
      fi
    fi
    
    # Basic non-empty validation
    if [[ -z "$user_input" ]]; then
      print_error "This field is required. Please enter a value."
      continue
    fi
    
    echo "$user_input"
    break
  done
}

# Interactive setup wizard
function interactive_setup() {
  echo ""
  echo "${STATUS_TARGET} Interactive Setup Wizard"
  echo "═══════════════════════════"
  echo "Let's configure your deployment environment step by step."
  echo ""
  
  # Generate smart defaults
  local current_dir=$(basename "$(pwd)")
  local parent_dir=$(basename "$(dirname "$(pwd)")")
  local git_repo_name=""
  if git remote get-url origin >/dev/null 2>&1; then
    git_repo_name=$(basename "$(git remote get-url origin)" .git 2>/dev/null || echo "")
  fi
  
  # Smart stack name default
  local default_stack_name="${git_repo_name:-${parent_dir:-my-app}}-production"
  default_stack_name=$(echo "$default_stack_name" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9-]/-/g' | sed 's/--*/-/g' | sed 's/^-\|-$//g')
  
  # Smart bucket name default (must be globally unique)
  local timestamp=$(date +%s)
  local default_bucket="${git_repo_name:-${parent_dir:-my-app}}-deployments-$timestamp"
  default_bucket=$(echo "$default_bucket" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9-]/-/g' | sed 's/--*/-/g' | sed 's/^-\|-$//g')
  
  # Find template files
  local template_candidates=()
  while IFS= read -r -d '' file; do
    template_candidates+=("$file")
  done < <(find . ../.. -name "*.yaml" -o -name "*.yml" -o -name "*.json" 2>/dev/null | grep -i -E "(template|stack|cloudformation)" | head -5 | tr '\n' '\0')
  
  local default_template=""
  if [[ ${#template_candidates[@]} -gt 0 ]]; then
    default_template="${template_candidates[0]}"
  fi
  
  # Find Lambda source directories
  local lambda_candidates=()
  while IFS= read -r -d '' dir; do
    lambda_candidates+=("$(dirname "$dir")")
  done < <(find . ../.. -name "*.js" -type f 2>/dev/null | grep -v node_modules | head -5 | tr '\n' '\0')
  
  local default_lambda_dir=""
  if [[ ${#lambda_candidates[@]} -gt 0 ]]; then
    # Remove duplicates and pick most likely candidate
    default_lambda_dir=$(printf '%s\n' "${lambda_candidates[@]}" | sort -u | head -1)
  fi
  
  echo "Step 1: CloudFormation Stack Configuration"
  echo "────────────────────────────────────────"
  
  STACK_NAME=$(prompt_for_variable "STACK_NAME" \
    "What should we name your CloudFormation stack?" \
    "$default_stack_name" \
    "^[a-zA-Z][a-zA-Z0-9-]*$")
  
  echo ""
  echo "Step 2: CloudFormation Template"
  echo "─────────────────────────────"
  
  if [[ -n "$default_template" ]]; then
    echo "${STATUS_INFO} Found potential template files:"
    printf '   • %s\n' "${template_candidates[@]}"
    echo ""
  fi
  
  TEMPLATE_FILE=$(prompt_for_variable "TEMPLATE_FILE" \
    "Path to your CloudFormation template file:" \
    "$default_template")
  
  # Validate template file exists
  while [[ ! -f "$TEMPLATE_FILE" ]]; do
    print_error "Template file not found: $TEMPLATE_FILE"
    TEMPLATE_FILE=$(prompt_for_variable "TEMPLATE_FILE" \
      "Please enter a valid path to your CloudFormation template:" \
      "")
  done
  
  echo ""
  echo "Step 3: S3 Deployment Bucket"
  echo "───────────────────────────"
  echo "${STATUS_INFO} This bucket will store your Lambda deployment packages."
  echo "${STATUS_INFO} Bucket names must be globally unique across all AWS accounts."
  
  BUCKET_NAME=$(prompt_for_variable "BUCKET_NAME" \
    "S3 bucket name for deployments:" \
    "$default_bucket" \
    "^[a-z0-9][a-z0-9.-]*[a-z0-9]$")
  
  echo ""
  echo "Step 4: AWS Configuration"
  echo "───────────────────────────"
  
  AWS_REGION=$(prompt_for_variable "AWS_REGION" \
    "AWS region for deployment:" \
    "$DEFAULT_REGION" \
    "^[a-z0-9-]+$")
  
  SECRET_NAME=$(prompt_for_variable "SECRET_NAME" \
    "AWS Secrets Manager secret name (if your template uses one):" \
    "${STACK_NAME}-secrets")
  
  echo ""
  echo "Step 5: Lambda Source Code"
  echo "────────────────────────────"
  
  if [[ -n "$default_lambda_dir" ]]; then
    echo "${STATUS_INFO} Found JavaScript files in these directories:"
    printf '   • %s\n' "${lambda_candidates[@]}" | sort -u
    echo ""
  fi
  
  LAMBDA_SOURCE_DIR=$(prompt_for_variable "LAMBDA_SOURCE_DIR" \
    "Path to your Lambda source code directory:" \
    "${default_lambda_dir:-$DEFAULT_LAMBDA_DIR}")
  
  echo ""
  echo "Step 6: Deployment Strategy"
  echo "─────────────────────────────"
  echo "${STATUS_INFO} Tag-based: Only deploy when you create git tags (recommended for production)"
  echo "${STATUS_INFO} Commit-based: Deploy on every git commit (good for development)"
  
  local deploy_strategy
  while true; do
    read -p "Deployment strategy (tags/commits) [tags]: " deploy_strategy
    deploy_strategy="${deploy_strategy:-tags}"
    case "$deploy_strategy" in
      "tags"|"tag"|"t")
        DEPLOY_ON_TAGS="true"
        break
        ;;
      "commits"|"commit"|"c")
        DEPLOY_ON_TAGS="false"
        break
        ;;
      *)
        print_error "Please enter 'tags' or 'commits'"
        ;;
    esac
  done
  
  echo ""
  echo "Step 7: Optional Features"
  echo "───────────────────────────"
  
  read -p "CloudFront Distribution ID for cache invalidation (optional): " CLOUDFRONT_DISTRIBUTION_ID
  
  # Create/update .env file
  echo ""
  echo "${STATUS_SAVE} Saving configuration to .env file..."
  
  cat > "$ENV_FILE" << EOF
# =============================================================================
# CloudFormation Stack Configuration
# =============================================================================
STACK_NAME=$STACK_NAME
TEMPLATE_FILE=$TEMPLATE_FILE
AWS_REGION=$AWS_REGION
SECRET_NAME=$SECRET_NAME

# =============================================================================
# S3 Deployment Configuration  
# =============================================================================
BUCKET_NAME=$BUCKET_NAME

# =============================================================================
# Lambda Configuration
# =============================================================================
LAMBDA_SOURCE_DIR=$LAMBDA_SOURCE_DIR

# =============================================================================
# Deployment Behavior
# =============================================================================
DEPLOY_ON_TAGS=$DEPLOY_ON_TAGS

EOF

  if [[ -n "$CLOUDFRONT_DISTRIBUTION_ID" ]]; then
    echo "# =============================================================================
# CloudFront Configuration
# =============================================================================
CLOUDFRONT_DISTRIBUTION_ID=$CLOUDFRONT_DISTRIBUTION_ID

" >> "$ENV_FILE"
  fi

  echo "# =============================================================================
# Auto-generated values (managed by deployment script)
# =============================================================================
# LAMBDA_S3_KEY=
# VERSION=
# GIT_COMMIT=
# GIT_BRANCH=
# GIT_TAG=
# LAST_DEPLOY_DATE=
# LAST_SUCCESSFUL_DEPLOY_DATE=
# LAST_DEPLOY_FAILED=
" >> "$ENV_FILE"

  print_success "Configuration saved to $ENV_FILE"
  echo ""
  
  # Offer to create S3 bucket if it doesn't exist
  echo "${STATUS_BUCKET} Checking if S3 bucket exists..."
  if ! aws s3 ls "s3://$BUCKET_NAME" --region "$AWS_REGION" >/dev/null 2>&1; then
    echo "${STATUS_PACKAGE} S3 bucket '$BUCKET_NAME' doesn't exist."
    read -p "Would you like me to create it? (y/N): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
      if aws s3 mb "s3://$BUCKET_NAME" --region "$AWS_REGION"; then
        print_success "S3 bucket created successfully"
      else
        print_error "Failed to create S3 bucket. You may need to choose a different name."
        print_info "Bucket names must be globally unique across all AWS accounts."
      fi
    fi
  else
    print_success "S3 bucket '$BUCKET_NAME' exists and is accessible"
  fi
  
  # Offer to create Lambda directory if it doesn't exist
  if [[ ! -d "$LAMBDA_SOURCE_DIR" ]]; then
    echo ""
    echo "${STATUS_CONFIG} Lambda source directory '$LAMBDA_SOURCE_DIR' doesn't exist."
    read -p "Would you like me to create it with a sample Lambda function? (y/N): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
      mkdir -p "$LAMBDA_SOURCE_DIR"
      create_sample_lambda_function "$LAMBDA_SOURCE_DIR" "$STACK_NAME"
      print_success "Created sample Lambda function in $LAMBDA_SOURCE_DIR"
      print_info "You can now customize the Lambda code in $LAMBDA_SOURCE_DIR/index.js"
    fi
  fi
  
  echo ""
  echo "${STATUS_COMPLETE} Setup Complete!"
  echo "═══════════════════"
  echo "Your deployment environment is now configured."
  echo ""
  echo "${STATUS_SUMMARY} Configuration Summary:"
  echo "   • Stack: $STACK_NAME"
  echo "   • Template: $TEMPLATE_FILE"
  echo "   • S3 Bucket: $BUCKET_NAME"
  echo "   • Region: $AWS_REGION"
  echo "   • Lambda Code: $LAMBDA_SOURCE_DIR"
  echo "   • Deploy Strategy: $([ "$DEPLOY_ON_TAGS" = "true" ] && echo "Git tags only" || echo "Every commit")"
  echo ""
  
  if [[ "$DEPLOY_ON_TAGS" == "true" ]]; then
    echo "${STATUS_INFO} Next steps:"
    echo "   1. The script will now start watching for git tags"
    echo "   2. When ready to deploy, create a tag:"
    echo "      git tag v1.0.0 && git push --tags"
    echo "   3. The script will automatically deploy your stack"
  else
    echo "${STATUS_INFO} Next steps:"
    echo "   1. The script will now start watching for git commits"
    echo "   2. Any new commit will trigger an automatic deployment"
    echo "   3. Make changes, commit, and watch the magic happen!"
  fi
  
  echo ""
  echo "${STATUS_WATCH} Starting deployment watcher..."
  echo ""
}

# Create sample Lambda function
function create_sample_lambda_function() {
  local lambda_dir="$1"
  local stack_name="$2"
  
  cat > "$lambda_dir/index.js" << 'EOF'
exports.handler = async (event) => {
    console.log('Event received:', JSON.stringify(event, null, 2));
    
    const response = {
        statusCode: 200,
        headers: {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*'
        },
        body: JSON.stringify({
            message: 'Hello from your Lambda function!',
            timestamp: new Date().toISOString(),
            event: event
        })
    };
    
    return response;
};
EOF

  cat > "$lambda_dir/package.json" << EOF
{
  "name": "$(echo "$stack_name" | sed 's/-/_/g')-lambda",
  "version": "1.0.0",
  "description": "Lambda function for $stack_name",
  "main": "index.js",
  "dependencies": {},
  "scripts": {
    "test": "echo \\"No tests specified\\" && exit 0"
  }
}
EOF
}

# Show startup summary
function show_startup_summary() {
  echo ""
  echo "${STATUS_SUMMARY} Deployment Configuration Summary:"
  echo "   • Stack Name: $STACK_NAME"
  echo "   • Template: $TEMPLATE_FILE"
  echo "   • S3 Bucket: $BUCKET_NAME"
  echo "   • AWS Region: $AWS_REGION"
  echo "   • Lambda Source: ${LAMBDA_SOURCE_DIR:-$DEFAULT_LAMBDA_DIR}"
  
  if [[ "$DEPLOY_ON_TAGS" == "true" ]]; then
    echo "   • Trigger: Git tags only"
    echo "   • Current Branch: $(get_git_branch)"
    if is_on_tagged_commit; then
      echo "   • Current Tag: $(get_latest_tag) ${STATUS_SUCCESS}"
    else
      echo "   • Current Tag: None (will not deploy until tagged)"
    fi
  else
    echo "   • Trigger: Every git commit"
    echo "   • Current Branch: $(get_git_branch)"
    echo "   • Current Commit: $(get_git_commit)"
  fi
  
  # Check if stack exists
  local stack_status=$(check_stack_status "$STACK_NAME")
  if [[ "$stack_status" == "DOES_NOT_EXIST" ]]; then
    echo "   • Stack Status: New stack (will be created)"
  else
    echo "   • Stack Status: $stack_status"
  fi
  
  echo ""
}