#!/bin/bash
# modules/deployment.sh - Main deployment orchestration

# Deploy CloudFormation stack
function deploy_stack() {
  # Check if we should deploy (based on tag settings)
  if ! should_deploy; then
    return 0
  fi
  
  # Check for uncommitted changes
  has_git_changes
  
  # Validate CloudFormation template first
  if ! validate_cloudformation_template; then
    echo ""
    echo "${STATUS_STOP} Template validation failed. Please fix template and try again."
    return 1
  fi
  
  # Package and upload Lambda function
  if ! package_and_upload_lambda; then
    print_error "Failed to package/upload Lambda function"
    return 1
  fi
  
  # Re-source .env to get updated LAMBDA_S3_KEY and VERSION
  source "$ENV_FILE"
  
  # Check if stack exists
  local stack_status=$(check_stack_status "$STACK_NAME")
  local is_new_stack=false
  
  if [[ "$stack_status" == "DOES_NOT_EXIST" ]]; then
    echo "${STATUS_CREATE} Stack '$STACK_NAME' does not exist - creating new stack"
    is_new_stack=true
  else
    echo "${STATUS_RELOAD} Stack '$STACK_NAME' exists with status: $stack_status - updating stack"
    
    # Check if stack is in a failed state
    case "$stack_status" in
      "CREATE_FAILED"|"ROLLBACK_COMPLETE")
        print_warning "Stack is in failed state: $stack_status"
        echo "${STATUS_CONFIG} You may need to delete and recreate the stack:"
        echo "   aws cloudformation delete-stack --stack-name $STACK_NAME --region $AWS_REGION"
        echo ""
        read -p "Continue with deployment anyway? (y/N): " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
          print_error "Deployment cancelled"
          return 1
        fi
        ;;
      "DELETE_IN_PROGRESS"|"DELETE_COMPLETE")
        print_error "Cannot deploy - stack is being/has been deleted"
        return 1
        ;;
      "CREATE_IN_PROGRESS"|"UPDATE_IN_PROGRESS"|"DELETE_IN_PROGRESS")
        print_error "Cannot deploy - stack operation already in progress"
        print_info "Wait for current operation to complete, then try again"
        return 1
        ;;
    esac
  fi
  
  echo "${STATUS_DEPLOY} Deploying CloudFormation stack: $STACK_NAME (Commit: $(get_git_commit))"
  update_env_var "LAST_DEPLOY_DATE" "$(date '+%Y-%m-%d %H:%M:%S')"

  # Deploy using aws cloudformation deploy (handles both create and update)
  # Build parameter overrides dynamically
  local param_overrides=""
  
  # Add system parameters (for backward compatibility)
  if [[ -n "$BUCKET_NAME" ]]; then
    param_overrides+=" BucketName=\"$BUCKET_NAME\""
  fi
  if [[ -n "$SECRET_NAME" ]]; then
    param_overrides+=" SecretName=\"$SECRET_NAME\""
  fi
  if [[ -n "$LAMBDA_S3_KEY" ]]; then
    param_overrides+=" LambdaS3Key=\"$LAMBDA_S3_KEY\""
  fi
  if [[ -n "$VERSION" ]]; then
    param_overrides+=" Version=\"$VERSION\""
  fi
  
  # Add custom parameters from CFN_FORGE_PARAMETERS
  if [[ -n "$CFN_FORGE_PARAMETERS" ]]; then
    echo "${STATUS_DATA} Adding custom parameters: $CFN_FORGE_PARAMETERS"
    
    # Parse comma-separated key=value pairs
    IFS=',' read -ra PARAM_PAIRS <<< "$CFN_FORGE_PARAMETERS"
    for param_pair in "${PARAM_PAIRS[@]}"; do
      # Extract key and value
      if [[ "$param_pair" =~ ^([^=]+)=(.*)$ ]]; then
        local param_key="${BASH_REMATCH[1]}"
        local param_value="${BASH_REMATCH[2]}"
        
        # Add to parameter overrides (escape quotes in values)
        param_overrides+=" ${param_key}=\"${param_value}\""
        echo "   • ${param_key} = ${param_value}"
      else
        print_warning "Invalid parameter format: $param_pair (expected key=value)"
      fi
    done
  fi
  
  echo "${STATUS_DEPLOY} Deploying with parameters: $param_overrides"
  
  local deploy_output
  if deploy_output=$(aws cloudformation deploy \
    --stack-name "$STACK_NAME" \
    --template-file "$TEMPLATE_FILE" \
    --capabilities CAPABILITY_NAMED_IAM CAPABILITY_IAM \
    --parameter-overrides $param_overrides \
    --region "$AWS_REGION" 2>&1); then

    update_env_var "LAST_SUCCESSFUL_DEPLOY_DATE" "$(date '+%Y-%m-%d %H:%M:%S')"
    
    if [[ "$is_new_stack" == true ]]; then
      echo "${STATUS_SUCCESS} New stack created successfully: $STACK_NAME"
    else
      print_success "Stack updated successfully: $STACK_NAME"
    fi
    
    echo "${STATUS_SUMMARY} Deployment details:"
    echo "   • Git Commit: $(git rev-parse HEAD)"
    echo "   • Git Branch: $(get_git_branch)" 
    echo "   • S3 Key: $LAMBDA_S3_KEY"
    echo "   • Stack Status: $(check_stack_status "$STACK_NAME")"
    
    # Show stack outputs if any
    local outputs
    if outputs=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" --region "$AWS_REGION" --query 'Stacks[0].Outputs[].{Key:OutputKey,Value:OutputValue}' --output table 2>/dev/null); then
      if [[ -n "$outputs" && "$outputs" != *"None"* ]]; then
        echo ""
        echo "${STATUS_DATA} Stack Outputs:"
        echo "$outputs"
      fi
    fi
    
    # Optional: Invalidate CloudFront cache if CLOUDFRONT_DISTRIBUTION_ID is set
    if [[ -n "$CLOUDFRONT_DISTRIBUTION_ID" ]]; then
      echo "${STATUS_RELOAD} Invalidating CloudFront cache..."
      aws cloudfront create-invalidation \
        --distribution-id "$CLOUDFRONT_DISTRIBUTION_ID" \
        --paths "/*" \
        --region "$AWS_REGION" || print_warning "CloudFront invalidation failed (non-critical)"
    fi
    
    mark_deploy_status "success"
    return 0
  else
    print_error "Stack deployment failed"
    echo ""
    echo "${STATUS_ANALYZE} Deployment error details:"
    echo "$deploy_output"
    echo ""
    
    # Parse deployment error
    if parse_cfn_deployment_error "$deploy_output"; then
      mark_deploy_status "success"
      return 0
    fi
    
    echo ""
    mark_deploy_status "failed"
    revert_version
    return 1
  fi
}

# Safe deployment wrapper that never exits
function safe_deploy_stack() {
  echo "${STATUS_DEPLOY} Starting deployment process..."
  
  # Wrap the entire deployment in error handling that never exits
  if deploy_stack; then
    print_success "Deployment completed successfully"
    return 0
  else
    print_warning "Deployment failed or was skipped"
    print_info "The script will continue watching for changes"
    echo "${STATUS_RELOAD} Make fixes and commit again to retry deployment"
    return 1
  fi
}

# Enhanced startup that never exits
function startup_checks() {
  echo "${STATUS_WATCH} Starting git-based deployment watcher..."

  # Check dependencies - continue even if some fail
  if ! check_dependencies; then
    print_warning "Some dependency issues detected - continuing anyway"
    print_info "Fix dependencies to ensure full functionality"
  fi

  # Validate environment - always succeeds (may trigger interactive setup)
  validate_environment

  # Show configuration summary
  if [[ -f "$ENV_FILE" ]]; then
    source "$ENV_FILE"
    show_startup_summary
  fi

  print_success "Startup checks completed - ready to watch for changes!"
}