#!/bin/bash

# Colores para la salida
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

# Función para mostrar mensajes de error
error() {
    echo -e "${RED}Error: $1${NC}"
}

# Función para mostrar mensajes de éxito
success() {
    echo -e "${GREEN}$1${NC}"
}

# Función para mostrar información
info() {
    echo -e "${BLUE}$1${NC}"
}

# Función para mostrar advertencias
warning() {
    echo -e "${YELLOW}$1${NC}"
}

# Función para mostrar procesos
process() {
    echo -e "${CYAN}$1${NC}"
}

# Función para verificar y crear estructura Docker si no existe
check_docker_structure() {
    local main_dir="docker"
    
    if [ -d "$main_dir" ]; then
        success "Estructura Docker ya existe en $main_dir/"
        return 0
    else
        warning "No se encontró estructura Docker. Creando..."
        
        # Crear directorio principal
        mkdir -p "$main_dir"
        cd "$main_dir"
        
        # Crear subdirectorios
        mkdir -p apache-logs postgres-backups src
        
        # Crear archivo .env con puertos por defecto
        cat > .env << EOF
# Database
DB_CONNECTION=pgsql
DB_HOST=db
DB_PORT=5432
DB_DATABASE=laravel
DB_USERNAME=postgres
DB_PASSWORD=password

# App
APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost:8081

# Postgres
POSTGRES_DB=laravel
POSTGRES_USER=postgres
POSTGRES_PASSWORD=password
EOF
        
        # Crear configuración de Apache
        cat > 000-default.conf << EOF
<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html/public

    <Directory /var/www/html>
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
EOF
        
        # Crear docker-compose.yml
        cat > docker-compose.yml << EOF
version: '3.8'

services:
  web:
    build: 
      context: .
      dockerfile: Dockerfile
    ports:
      - "8081:80"
    volumes:
      - ./src:/var/www/html
      - ./apache-logs:/var/log/apache2
    depends_on:
      - db
    networks:
      - backend-network
    env_file:
      - .env
    container_name: php-web
    restart: unless-stopped

  db:
    image: postgres:15
    env_file:
      - .env
    volumes:
      - pgdata:/var/lib/postgresql/data
      - ./postgres-backups:/backups
    networks:
      - backend-network
    container_name: db-postgres
    restart: unless-stopped
    ports:
      - "5432:5432"

networks:
  backend-network:
    driver: bridge

volumes:
  pgdata:
    driver: local
EOF
        
        # Crear Dockerfile
        cat > Dockerfile << EOF
FROM php:8.1-apache

# Instalar dependencias del sistema
RUN apt-get update && apt-get install -y \\
    libpq-dev \\
    libzip-dev \\
    libpng-dev \\
    libjpeg-dev \\
    libfreetype6-dev \\
    zip \\
    unzip \\
    git \\
    curl \\
    && docker-php-ext-configure gd --with-freetype --with-jpeg \\
    && docker-php-ext-install -j\$(nproc) \\
        pdo \\
        pdo_pgsql \\
        pgsql \\
        zip \\
        gd \\
        bcmath \\
    && a2enmod rewrite

# Instalar Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# Configurar Apache
COPY 000-default.conf /etc/apache2/sites-available/000-default.conf

# Configurar permisos y directorio de trabajo
RUN chown -R www-data:www-data /var/www/html \\
    && usermod -u 1000 www-data \\
    && groupmod -g 1000 www-data

WORKDIR /var/www/html
EOF
        
        success "Estructura Docker creada correctamente en $main_dir/"
        cd ..
        return 1
    fi
}

# Función para seleccionar tipo de framework
select_framework_type() {
    local framework="$1"
    
    if [ "$framework" == "yii" ]; then
        echo ""
        info "Selecciona el tipo de Yii:"
        echo "  1. Yii 3 (última versión)"
        echo "  2. Yii 2 Basic"
        echo "  3. Yii 2 Advanced"
        echo ""
        
        while true; do
            read -p "Opción (1-3): " yii_choice
            case $yii_choice in
                1)
                    echo "yii3"
                    break
                    ;;
                2)
                    echo "yii2-basic"
                    break
                    ;;
                3)
                    echo "yii2-advanced"
                    break
                    ;;
                *)
                    error "Opción inválida. Por favor elige 1, 2 o 3."
                    ;;
            esac
        done
    else
        echo ""
    fi
}

# Función para crear proyecto Laravel
create_laravel_project() {
    local project_name="$1"
    local framework_dir="$2"
    
    process "Creando proyecto Laravel: $project_name"
    docker-compose exec web composer create-project --prefer-dist laravel/laravel "$project_name"
    
    # Configurar permisos
    docker-compose exec web bash -c "cd $project_name && chmod -R 775 storage bootstrap/cache"
    docker-compose exec web bash -c "cd $project_name && chown -R www-data:www-data storage bootstrap/cache"
}

# Función para crear proyecto Yii3
create_yii3_project() {
    local project_name="$1"
    local framework_dir="$2"
    
    process "Creando proyecto Yii3: $project_name"
    docker-compose exec web composer create-project --prefer-dist yiisoft/yii-project-template "$project_name"
    
    # Configurar base de datos
    docker-compose exec web bash -c "cd $project_name && cp .env.example .env"
    docker-compose exec web bash -c "cd $project_name && sed -i 's/DB_DSN=sqlite:\/\/\/\/var\/www\/html\/runtime\/database.sqlite/DB_DSN=pgsql:host=db;dbname=laravel/' .env"
    docker-compose exec web bash -c "cd $project_name && sed -i 's/DB_USERNAME=/DB_USERNAME=postgres/' .env"
    docker-compose exec web bash -c "cd $project_name && sed -i 's/DB_PASSWORD=/DB_PASSWORD=password/' .env"
}

# Función para crear proyecto Yii2 Basic
create_yii2_basic_project() {
    local project_name="$1"
    local framework_dir="$2"
    
    process "Creando proyecto Yii2 Basic: $project_name"
    docker-compose exec web composer create-project --prefer-dist yiisoft/yii2-app-basic "$project_name"
    
    # Configurar base de datos
    docker-compose exec web bash -c "cd $project_name && sed -i \"s/'dsn' => 'mysql:host=localhost;dbname=yii2basic',/'dsn' => 'pgsql:host=db;dbname=laravel',/\" config/db.php"
    docker-compose exec web bash -c "cd $project_name && sed -i \"s/'username' => 'root',/'username' => 'postgres',/\" config/db.php"
    docker-compose exec web bash -c "cd $project_name && sed -i \"s/'password' => '',/'password' => 'password',/\" config/db.php"
}

# Función para crear proyecto Yii2 Advanced
create_yii2_advanced_project() {
    local project_name="$1"
    local framework_dir="$2"
    
    process "Creando proyecto Yii2 Advanced: $project_name"
    docker-compose exec web composer create-project --prefer-dist yiisoft/yii2-app-advanced "$project_name"
    
    # Configurar entorno
    docker-compose exec web bash -c "cd $project_name && php init --env=Development --overwrite=All"
    
    # Configurar base de datos
    docker-compose exec web bash -c "cd $project_name && sed -i \"s/'dsn' => 'mysql:host=localhost;dbname=yii2advanced',/'dsn' => 'pgsql:host=db;dbname=laravel',/\" common/config/main-local.php"
    docker-compose exec web bash -c "cd $project_name && sed -i \"s/'username' => 'root',/'username' => 'postgres',/\" common/config/main-local.php"
    docker-compose exec web bash -c "cd $project_name && sed -i \"s/'password' => '',/'password' => 'password',/\" common/config/main-local.php"
}

# Función para crear nuevo proyecto
create_new_project() {
    local project_name="$1"
    local framework="$2"
    local framework_type="$3"
    
    info "Creando nuevo proyecto $project_name con $framework $framework_type en docker/src/$project_name/..."
    
    # Iniciar contenedores Docker si no están ejecutándose
    if ! docker-compose ps | grep -q "Up"; then
        process "Iniciando contenedores Docker..."
        docker-compose up -d
    fi
    
    # Instalar Composer en el contenedor si es necesario
    if ! docker-compose exec web composer --version > /dev/null 2>&1; then
        process "Instalando Composer en el contenedor..."
        docker-compose exec web curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
    fi
    
    # Crear proyecto según el framework y tipo
    case $framework in
        "laravel")
            create_laravel_project "$project_name"
            ;;
        "yii")
            case $framework_type in
                "yii3")
                    create_yii3_project "$project_name"
                    ;;
                "yii2-basic")
                    create_yii2_basic_project "$project_name"
                    ;;
                "yii2-advanced")
                    create_yii2_advanced_project "$project_name"
                    ;;
            esac
            ;;
    esac
    
    if [ $? -ne 0 ]; then
        error "Error al crear el proyecto."
        return 1
    fi
    
    success "Proyecto $project_name ($framework $framework_type) creado correctamente en docker/src/$project_name/"
    return 0
}

# Función para mostrar instrucciones de uso
show_instructions() {
    local project_name="$1"
    local framework="$2"
    local framework_type="$3"
    
    echo ""
    success "¡Proceso completado!"
    echo ""
    
    info "Estructura del proyecto:"
    echo "  - docker/ (configuración Docker)"
    echo "  - docker/src/$project_name/ (proyecto $framework $framework_type)"
    echo ""
    
    info "Para iniciar el proyecto:"
    echo "  1. cd docker"
    echo "  2. docker-compose up -d"
    echo ""
    info "Accesos:"
    echo "  - Aplicación web: http://localhost:8081/"
    
    if [ "$framework" == "yii" ] && [ "$framework_type" == "yii2-advanced" ]; then
        echo "  - Frontend: http://localhost:8081/$project_name/frontend/web/"
        echo "  - Backend: http://localhost:8081/$project_name/backend/web/"
    elif [ "$framework" == "yii" ] && [ "$framework_type" == "yii2-basic" ]; then
        echo "  - Aplicación: http://localhost:8081/$project_name/web/"
    fi
    
    echo "  - PostgreSQL: localhost:5432"
    echo "  - Usuario BD: postgres"
    echo "  - Password BD: password"
    echo ""
    
    info "Comandos útiles:"
    echo "  - Ver logs: docker-compose logs"
    echo "  - Detener contenedores: docker-compose down"
    echo "  - Ejecutar comandos en el contenedor: docker-compose exec web [comando]"
    echo ""
    
    if [ "$framework" == "laravel" ]; then
        info "Para Laravel:"
        echo "  - Ejecutar migraciones: docker-compose exec web bash -c 'cd $project_name && php artisan migrate'"
    elif [ "$framework" == "yii" ]; then
        info "Para Yii:"
        echo "  - Ejecutar migraciones: docker-compose exec web bash -c 'cd $project_name && php yii migrate'"
    fi
}

# Función principal
main() {
    echo "=========================================="
    echo " GENERADOR DE PROYECTOS CON DOCKER"
    echo "=========================================="
    echo ""
    
    # Verificar y crear estructura Docker si es necesario
    check_docker_structure
    
    # Cambiar al directorio docker
    cd docker
    
    # Preguntar por el tipo de proyecto
    while true; do
        read -p "¿Qué tipo de proyecto quieres crear? (laravel/yii): " framework
        framework=$(echo "$framework" | tr '[:upper:]' '[:lower:]')
        
        if [[ "$framework" == "laravel" || "$framework" == "yii" ]]; then
            break
        else
            error "Por favor, ingresa 'laravel' o 'yii'"
        fi
    done
    
    # Seleccionar tipo de framework si es Yii
    framework_type=""
    if [ "$framework" == "yii" ]; then
        framework_type=$(select_framework_type "$framework")
    fi
    
    # Preguntar nombre del proyecto
    while true; do
        read -p "Nombre del proyecto (solo letras, números y guiones): " project_name
        if [[ "$project_name" =~ ^[a-zA-Z0-9_-]+$ ]]; then
            # Verificar si el proyecto ya existe
            if [ -d "src/$project_name" ]; then
                error "El proyecto $project_name ya existe en docker/src/"
            else
                break
            fi
        else
            error "Nombre inválido. Solo se permiten letras, números y guiones."
        fi
    done
    
    # Crear el proyecto
    create_new_project "$project_name" "$framework" "$framework_type"
    
    if [ $? -eq 0 ]; then
        # Mostrar instrucciones
        show_instructions "$project_name" "$framework" "$framework_type"
    else
        error "No se pudo crear el proyecto."
    fi
}

# Ejecutar función principal
main "$@"