#!/bin/bash

# ========================================
# Script: propagate-core-improvements.sh
# Descripción: Propaga mejoras del core CD-System a proyectos existentes
# Uso: ./propagate-core-improvements.sh <url_repositorio_proyecto> [opciones]
# ========================================

set -euo pipefail

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

# Configuración por defecto
CD_SYSTEM_REPO="https://github.com/LACOMPANIADIGITAL/cd-system.git"
CD_SYSTEM_BRANCH="cd-system"
PROJECT_BRANCH="cd-system"
TEMP_REMOTE="cd-system-core"
DO_PUSH="no"
DRY_RUN="no"
SELECTIVE="no"  # Si es "yes", permite seleccionar qué propagar

# Función para mostrar mensajes con colores
print_message() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

print_step() {
    echo -e "${BLUE}[STEP]${NC} $1"
}

print_success() {
    echo -e "${GREEN}[✓]${NC} $1"
}

print_dry_run() {
    echo -e "${PURPLE}[DRY-RUN]${NC} $1"
}

usage() {
    cat <<EOF
Uso: $(basename "$0") <url_repositorio_proyecto> [opciones]

Opciones:
  --core-url URL          URL del repo CD-System (default: $CD_SYSTEM_REPO)
  --core-branch NAME     Rama en CD-System (default: $CD_SYSTEM_BRANCH)
  --project-branch NAME   Rama en el proyecto (default: $PROJECT_BRANCH)
  --push yes|no           Hacer push después de propagar (default: $DO_PUSH)
  --dry-run               Simular sin hacer cambios (default: $DO_PUSH)
  --selective             Seleccionar qué propagar interactivamente
  -h, --help              Mostrar esta ayuda

Ejemplos:
  $(basename "$0") https://github.com/LACOMPANIADIGITAL/proyecto.git
  $(basename "$0") https://github.com/LACOMPANIADIGITAL/proyecto.git --push yes
  $(basename "$0") https://github.com/LACOMPANIADIGITAL/proyecto.git --dry-run --selective
EOF
}

# Parseo de argumentos
PROJECT_REPO=""
while [[ $# -gt 0 ]]; do
    case "$1" in
        --core-url)       CD_SYSTEM_REPO="$2"; shift 2 ;;
        --core-branch)    CD_SYSTEM_BRANCH="$2"; shift 2 ;;
        --project-branch) PROJECT_BRANCH="$2"; shift 2 ;;
        --push)           DO_PUSH="$2"; shift 2 ;;
        --dry-run)        DRY_RUN="yes"; shift ;;
        --selective)      SELECTIVE="yes"; shift ;;
        -h|--help)        usage; exit 0 ;;
        *)
            if [ -z "$PROJECT_REPO" ]; then
                PROJECT_REPO="$1"
            else
                print_error "Opción desconocida: $1"
                usage
                exit 1
            fi
            shift
            ;;
    esac
done

# Validar que se proporcione el repositorio del proyecto
if [ -z "$PROJECT_REPO" ]; then
    print_error "Debes proporcionar la URL del repositorio del proyecto"
    usage
    exit 1
fi

print_message "═══════════════════════════════════════════════════════════"
print_message "Propagación de Mejoras del Core CD-System"
print_message "═══════════════════════════════════════════════════════════"
echo
print_message "Repositorio proyecto: ${CYAN}$PROJECT_REPO${NC}"
print_message "Repositorio core:    ${CYAN}$CD_SYSTEM_REPO${NC}"
print_message "Rama core:          ${CYAN}$CD_SYSTEM_BRANCH${NC}"
print_message "Rama proyecto:      ${CYAN}$PROJECT_BRANCH${NC}"
if [ "$DRY_RUN" == "yes" ]; then
    print_dry_run "MODO DRY-RUN: No se harán cambios reales"
fi
echo

# Verificar que estamos en un repositorio git
if ! git rev-parse --git-dir > /dev/null 2>&1; then
    print_error "No estás en un repositorio git válido"
    print_message "Este script debe ejecutarse desde el repositorio CD-System"
    exit 1
fi

# Verificar que estamos en la rama cd-system
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ "$CURRENT_BRANCH" != "$CD_SYSTEM_BRANCH" ]; then
    print_warning "No estás en la rama '$CD_SYSTEM_BRANCH' (estás en '$CURRENT_BRANCH')"
    read -p "¿Deseas cambiar a la rama '$CD_SYSTEM_BRANCH'? (y/N): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        git checkout "$CD_SYSTEM_BRANCH"
    else
        print_error "Operación cancelada"
        exit 1
    fi
fi

# Verificar que el working directory esté limpio
if ! git diff-index --quiet HEAD --; then
    print_warning "Hay cambios sin commitear en el repositorio"
    read -p "¿Deseas continuar de todos modos? (y/N): " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        print_error "Operación cancelada"
        exit 1
    fi
fi

# Crear directorio temporal para clonar el proyecto
TEMP_DIR=$(mktemp -d -t cd-system-propagate-XXXXXX)
trap "rm -rf $TEMP_DIR" EXIT

print_step "1. Clonando repositorio del proyecto en directorio temporal..."
if [ "$DRY_RUN" == "yes" ]; then
    print_dry_run "git clone --branch $PROJECT_BRANCH $PROJECT_REPO $TEMP_DIR"
else
    if ! git clone --branch "$PROJECT_BRANCH" "$PROJECT_REPO" "$TEMP_DIR" 2>/dev/null; then
        print_warning "No se pudo clonar la rama '$PROJECT_BRANCH', intentando clonar y crear la rama..."
        git clone "$PROJECT_REPO" "$TEMP_DIR"
        cd "$TEMP_DIR"
        git checkout -b "$PROJECT_BRANCH" 2>/dev/null || git checkout "$PROJECT_BRANCH" 2>/dev/null || true
        cd - > /dev/null
    fi
    print_success "Repositorio clonado"
fi

# Agregar remote del core en el proyecto clonado
print_step "2. Configurando remote del core en el proyecto..."
if [ "$DRY_RUN" == "yes" ]; then
    print_dry_run "cd $TEMP_DIR && git remote add $TEMP_REMOTE $CD_SYSTEM_REPO"
else
    cd "$TEMP_DIR"

    # Remover remote si ya existe
    if git remote | grep -q "^$TEMP_REMOTE$"; then
        git remote remove "$TEMP_REMOTE" 2>/dev/null || true
    fi

    git remote add "$TEMP_REMOTE" "$CD_SYSTEM_REPO"
    print_success "Remote del core configurado"

    # Fetch del core
    print_step "3. Descargando última versión del core..."
    git fetch "$TEMP_REMOTE" "$CD_SYSTEM_BRANCH"
    print_success "Core descargado"

    # Verificar que .gitattributes esté presente
    if [ ! -f ".gitattributes" ]; then
        print_warning ".gitattributes no encontrado en el proyecto"
        print_message "Copiando .gitattributes desde el core..."
        cp "$(git rev-parse --show-toplevel)/.gitattributes" .gitattributes
        git add .gitattributes
        git commit -m "chore: Agregar .gitattributes para protección de archivos del sistema" || true
        print_success ".gitattributes agregado"
    else
        print_success ".gitattributes ya existe"
    fi

    # Hacer merge del core
    print_step "4. Integrando mejoras del core..."
    print_message "Los archivos protegidos se mantendrán automáticamente gracias a .gitattributes"

    if git merge --no-edit --no-ff "$TEMP_REMOTE/$CD_SYSTEM_BRANCH" -m "chore: Integrar mejoras del core CD-System"; then
        print_success "Merge completado exitosamente"
    else
        print_warning "Se detectaron conflictos durante el merge"
        print_message "Los archivos protegidos (config/cd-system.php, config/site.php, assets) deberían mantenerse automáticamente"
        print_message "Revisa los conflictos y resuélvelos manualmente:"
        echo "  cd $TEMP_DIR"
        echo "  git status"
        echo "  # Resolver conflictos"
        echo "  git add ."
        echo "  git commit"

        if [ "$DO_PUSH" == "yes" ]; then
            print_warning "No se hará push debido a conflictos pendientes"
            DO_PUSH="no"
        fi
    fi

    # Remover remote temporal
    git remote remove "$TEMP_REMOTE"

    cd - > /dev/null
fi

# Push si está habilitado
if [ "$DO_PUSH" == "yes" ] && [ "$DRY_RUN" != "yes" ]; then
    print_step "5. Pusheando cambios al repositorio del proyecto..."
    cd "$TEMP_DIR"
    if git push origin "$PROJECT_BRANCH"; then
        print_success "Cambios pusheados exitosamente"
    else
        print_error "Error al hacer push"
        print_message "Puedes hacer push manualmente:"
        echo "  cd $TEMP_DIR"
        echo "  git push origin $PROJECT_BRANCH"
    fi
    cd - > /dev/null
elif [ "$DRY_RUN" == "yes" ]; then
    print_dry_run "Push deshabilitado en modo dry-run"
fi

echo
print_message "═══════════════════════════════════════════════════════════"
print_success "¡Propagación completada!"
print_message "═══════════════════════════════════════════════════════════"
echo

if [ "$DRY_RUN" != "yes" ]; then
    print_message "Directorio temporal: ${CYAN}$TEMP_DIR${NC}"
    print_message "Puedes revisar los cambios antes de hacer push manualmente"
    echo
    print_message "Para hacer push manualmente:"
    echo "  cd $TEMP_DIR"
    echo "  git push origin $PROJECT_BRANCH"
fi

echo
print_message "═══════════════════════════════════════════════════════════"

