#!/usr/bin/env bash

# AI-Powered Template Creation Workflow
# Demonstrates the complete AI workflow from description to validated template

set -euo pipefail

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# Script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEMP_DIR="${SCRIPT_DIR}/temp"
OUTPUT_DIR="${SCRIPT_DIR}/generated"

# Cleanup function
cleanup() {
    echo -e "${CYAN}Cleaning up temporary files...${NC}"
    rm -rf "${TEMP_DIR}"
}

trap cleanup EXIT

# Create directories
mkdir -p "${TEMP_DIR}" "${OUTPUT_DIR}"

# Print header
print_header() {
    local text="$1"
    echo ""
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}${text}${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
}

# Print step
print_step() {
    local step="$1"
    local desc="$2"
    echo -e "${GREEN}[STEP ${step}]${NC} ${desc}"
    echo ""
}

# Print command
print_command() {
    local cmd="$1"
    echo -e "${CYAN}\$ ${cmd}${NC}"
}

# Print output
print_output() {
    local output="$1"
    echo -e "${YELLOW}${output}${NC}"
}

# Print success
print_success() {
    local msg="$1"
    echo -e "${GREEN}✓ ${msg}${NC}"
}

# Print error
print_error() {
    local msg="$1"
    echo -e "${RED}✗ ${msg}${NC}"
}

# Mock AI generate function (simulates ggen ai generate --mock)
mock_ai_generate() {
    local prompt="$1"
    local output_file="$2"

    # Simple pattern matching for mock responses
    if [[ "$prompt" == *"User"* || "$prompt" == *"user"* ]]; then
        cat > "$output_file" <<'EOF'
# User Template
# Generated by ggen AI (mock mode)

struct User {
    id: uuid,
    name: string {
        min_length: 1,
        max_length: 100
    },
    email: string {
        pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
    },
    created_at: timestamp
}

# Basic validation rules
validation {
    name: required,
    email: required, unique
}
EOF
    else
        cat > "$output_file" <<'EOF'
# Generated Template
# Generated by ggen AI (mock mode)

struct GeneratedType {
    id: uuid,
    data: string,
    created_at: timestamp
}
EOF
    fi
}

# Mock AI validate function
mock_ai_validate() {
    local template_file="$1"
    local has_issues=false

    echo "Validating template: $template_file"
    echo ""

    # Check for basic patterns
    if ! grep -q "pattern:" "$template_file" && grep -q "email" "$template_file"; then
        print_error "Warning: Field 'email' lacks validation pattern"
        has_issues=true
    fi

    if ! grep -q "validation {" "$template_file"; then
        print_error "Warning: No validation rules defined"
        has_issues=true
    fi

    if ! $has_issues; then
        print_success "Valid template structure"
        print_success "All types are defined"
        print_success "Proper validation rules"
        echo ""
        echo -e "${GREEN}Issues: 0${NC}"
        return 0
    else
        echo ""
        echo -e "${YELLOW}Issues: 2 warnings${NC}"
        return 1
    fi
}

# Main workflow
main() {
    print_header "AI-Powered Template Creation Workflow"

    echo "This script demonstrates the complete AI workflow:"
    echo "1. Generate template from description (mock mode)"
    echo "2. Validate generated template"
    echo "3. Iterate and improve based on feedback"
    echo "4. Generate final code"
    echo ""
    echo "Note: Using --mock flag (no API keys required)"
    echo ""
    read -p "Press Enter to continue..."

    # ================================
    # STEP 1: Initial Generation
    # ================================
    print_header "STEP 1: Generate Template from Description"

    print_step "1" "Generate initial template"

    PROMPT="A User struct with id, name, email, and timestamps"
    print_command "ggen ai generate --mock \"${PROMPT}\""
    echo ""

    print_output "Generating template from description..."
    mock_ai_generate "$PROMPT" "${TEMP_DIR}/user_v1.ggen"
    sleep 1

    print_success "Template generated: user_v1.ggen"
    echo ""
    echo "Generated template:"
    echo "-------------------"
    cat "${TEMP_DIR}/user_v1.ggen"
    echo "-------------------"
    echo ""
    read -p "Press Enter to continue..."

    # ================================
    # STEP 2: Validation
    # ================================
    print_header "STEP 2: Validate Generated Template"

    print_step "2" "Check for issues and warnings"

    print_command "ggen ai validate ${TEMP_DIR}/user_v1.ggen"
    echo ""

    if mock_ai_validate "${TEMP_DIR}/user_v1.ggen"; then
        print_success "Validation passed!"
    else
        print_error "Validation found issues - need to improve"
    fi
    echo ""
    read -p "Press Enter to continue..."

    # ================================
    # STEP 3: Improve Based on Feedback
    # ================================
    print_header "STEP 3: Improve Template Based on Validation"

    print_step "3" "Generate improved version with validation feedback"

    IMPROVED_PROMPT="A User struct with:
- id (UUID, required, unique)
- name (string, 1-100 chars, required)
- email (string, validated email format, required, unique)
- created_at (timestamp, auto-generated)
- updated_at (timestamp, auto-updated)

Include validation rules and constraints."

    print_command "ggen ai generate --mock \"${IMPROVED_PROMPT}\""
    echo ""

    print_output "Generating improved template with validations..."

    # Create improved template
    cat > "${TEMP_DIR}/user_v2.ggen" <<'EOF'
# User Template (Improved)
# Generated by ggen AI (mock mode)
# Includes proper validation rules and constraints

struct User {
    id: uuid {
        required: true,
        unique: true
    },
    name: string {
        min_length: 1,
        max_length: 100,
        required: true
    },
    email: string {
        pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
        required: true,
        unique: true
    },
    created_at: timestamp {
        auto: "now"
    },
    updated_at: timestamp {
        auto: "update"
    }
}

# Validation rules
validation {
    name: required, length(1, 100),
    email: required, unique, email_format,
    id: required, unique
}

# Indexes for performance
indexes {
    email: unique,
    created_at: standard
}
EOF

    sleep 1
    print_success "Improved template generated: user_v2.ggen"
    echo ""
    echo "Improved template:"
    echo "-------------------"
    cat "${TEMP_DIR}/user_v2.ggen"
    echo "-------------------"
    echo ""
    read -p "Press Enter to continue..."

    # ================================
    # STEP 4: Re-validate Improvements
    # ================================
    print_header "STEP 4: Re-validate Improved Template"

    print_step "4" "Verify all issues are resolved"

    print_command "ggen ai validate ${TEMP_DIR}/user_v2.ggen"
    echo ""

    print_success "Valid template structure"
    print_success "All types are defined"
    print_success "Proper validation rules"
    print_success "Performance optimizations applied"
    echo ""
    echo -e "${GREEN}Issues: 0${NC}"
    echo ""
    read -p "Press Enter to continue..."

    # ================================
    # STEP 5: Generate Code
    # ================================
    print_header "STEP 5: Generate Final Code"

    print_step "5" "Generate Rust implementation from validated template"

    print_command "ggen generate ${TEMP_DIR}/user_v2.ggen --language rust --output ${OUTPUT_DIR}/"
    echo ""

    print_output "Generating Rust code..."

    # Create mock Rust output
    cat > "${OUTPUT_DIR}/user.rs" <<'EOF'
// Generated by ggen from user_v2.ggen
// DO NOT EDIT: This file is automatically generated

use uuid::Uuid;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
    pub id: Uuid,
    pub name: String,
    pub email: String,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

impl User {
    /// Create a new User with auto-generated id and timestamps
    pub fn new(name: String, email: String) -> Result<Self, ValidationError> {
        Self::validate_name(&name)?;
        Self::validate_email(&email)?;

        Ok(User {
            id: Uuid::new_v4(),
            name,
            email,
            created_at: Utc::now(),
            updated_at: Utc::now(),
        })
    }

    /// Validate name field (1-100 characters)
    fn validate_name(name: &str) -> Result<(), ValidationError> {
        if name.is_empty() || name.len() > 100 {
            return Err(ValidationError::InvalidName);
        }
        Ok(())
    }

    /// Validate email field (proper email format)
    fn validate_email(email: &str) -> Result<(), ValidationError> {
        let email_regex = regex::Regex::new(
            r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
        ).unwrap();

        if !email_regex.is_match(email) {
            return Err(ValidationError::InvalidEmail);
        }
        Ok(())
    }

    /// Update the user's information
    pub fn update(&mut self, name: Option<String>, email: Option<String>) -> Result<(), ValidationError> {
        if let Some(new_name) = name {
            Self::validate_name(&new_name)?;
            self.name = new_name;
        }

        if let Some(new_email) = email {
            Self::validate_email(&new_email)?;
            self.email = new_email;
        }

        self.updated_at = Utc::now();
        Ok(())
    }
}

#[derive(Debug, thiserror::Error)]
pub enum ValidationError {
    #[error("Invalid name: must be 1-100 characters")]
    InvalidName,
    #[error("Invalid email format")]
    InvalidEmail,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_valid_user_creation() {
        let user = User::new(
            "John Doe".to_string(),
            "john@example.com".to_string()
        );
        assert!(user.is_ok());
    }

    #[test]
    fn test_invalid_email() {
        let user = User::new(
            "John Doe".to_string(),
            "invalid-email".to_string()
        );
        assert!(user.is_err());
    }

    #[test]
    fn test_name_too_long() {
        let long_name = "a".repeat(101);
        let user = User::new(
            long_name,
            "john@example.com".to_string()
        );
        assert!(user.is_err());
    }
}
EOF

    sleep 1
    print_success "Code generated: ${OUTPUT_DIR}/user.rs"
    echo ""
    echo "Generated Rust code (excerpt):"
    echo "-------------------"
    head -n 30 "${OUTPUT_DIR}/user.rs"
    echo "... (see ${OUTPUT_DIR}/user.rs for full code)"
    echo "-------------------"
    echo ""

    # ================================
    # Summary
    # ================================
    print_header "Workflow Complete!"

    echo "Summary of AI workflow:"
    echo ""
    print_success "Generated initial template from description"
    print_success "Validated and identified issues"
    print_success "Improved template based on feedback"
    print_success "Re-validated to ensure quality"
    print_success "Generated production-ready Rust code"
    echo ""

    echo "Generated files:"
    echo "  - ${TEMP_DIR}/user_v1.ggen (initial template)"
    echo "  - ${TEMP_DIR}/user_v2.ggen (improved template)"
    echo "  - ${OUTPUT_DIR}/user.rs (generated Rust code)"
    echo ""

    echo "Next steps:"
    echo "  1. Review generated code in ${OUTPUT_DIR}/"
    echo "  2. Customize template in ${TEMP_DIR}/user_v2.ggen"
    echo "  3. Try your own prompts with 'ggen ai generate --mock'"
    echo "  4. Read README.md for best practices"
    echo "  5. Explore validation-examples/ for more examples"
    echo ""

    echo -e "${GREEN}🎉 AI workflow completed successfully!${NC}"
    echo ""
}

# Run main workflow
main
