#!/bin/bash
# Setup script for {{ cookiecutter.project_name }}
# Handles virtual environment creation and dependency installation across different systems

set -e  # Exit on any error

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

# Function to print colored output
print_status() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

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

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

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

# Check if command exists
command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# Check Python version
check_python_version() {
    if command_exists python3; then
        PYTHON_CMD="python3"
    elif command_exists python; then
        PYTHON_CMD="python"
    else
        print_error "Python is not installed. Please install Python 3.10 or higher."
        exit 1
    fi

    # Check Python version
    PYTHON_VERSION=$($PYTHON_CMD -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')")
    REQUIRED_VERSION="3.10"

    if ! $PYTHON_CMD -c "import sys; exit(0 if sys.version_info >= (3, 10) else 1)"; then
        print_error "Python $REQUIRED_VERSION or higher is required. Found: $PYTHON_VERSION"
        exit 1
    fi

    print_success "Python $PYTHON_VERSION found"
}

# Install UV if not present
install_uv() {
    if ! command_exists uv; then
        print_status "Installing UV package manager..."
        if command_exists curl; then
            curl -LsSf https://astral.sh/uv/install.sh | sh
            export PATH="$HOME/.cargo/bin:$PATH"
        elif command_exists pip || command_exists pip3; then
            if command_exists pip3; then
                pip3 install uv
            else
                pip install uv
            fi
        else
            print_error "Cannot install UV. Please install curl or pip first."
            exit 1
        fi
        print_success "UV installed successfully"
    else
        print_success "UV already installed"
    fi
}

# Setup with UV
setup_with_uv() {
    print_status "Setting up project with UV..."

    # Initialize UV project if not already done
    if [ ! -f "uv.lock" ]; then
        uv init --no-readme --python "$PYTHON_CMD"
    fi

    # Install dependencies
    print_status "Installing dependencies..."
    uv sync

    {% if cookiecutter.use_pre_commit == "yes" -%}
    # Install pre-commit hooks
    print_status "Installing pre-commit hooks..."
    uv run pre-commit install
    {% endif -%}

    print_success "Project setup complete with UV!"
    print_status "To activate the environment, run: source .venv/bin/activate"
    print_status "Or use UV commands directly: uv run {{ cookiecutter.project_slug }} --help"
}

# Setup with Poetry
setup_with_poetry() {
    print_status "Setting up project with Poetry..."

    # Install Poetry if not present
    if ! command_exists poetry; then
        print_status "Installing Poetry..."
        if command_exists curl; then
            curl -sSL https://install.python-poetry.org | $PYTHON_CMD -
            export PATH="$HOME/.local/bin:$PATH"
        else
            print_error "Poetry not found and curl not available. Please install Poetry manually."
            exit 1
        fi
    fi

    # Configure Poetry to create virtual environment in project directory
    poetry config virtualenvs.in-project true

    # Install dependencies
    print_status "Installing dependencies..."
    poetry install

    {% if cookiecutter.use_pre_commit == "yes" -%}
    # Install pre-commit hooks
    print_status "Installing pre-commit hooks..."
    poetry run pre-commit install
    {% endif -%}

    print_success "Project setup complete with Poetry!"
    print_status "To activate the environment, run: poetry shell"
    print_status "Or use Poetry commands: poetry run {{ cookiecutter.project_slug }} --help"
}

# Setup with pip/venv
setup_with_pip() {
    print_status "Setting up project with pip and venv..."

    # Create virtual environment
    if [ ! -d ".venv" ]; then
        print_status "Creating virtual environment..."
        $PYTHON_CMD -m venv .venv
    fi

    # Activate virtual environment
    if [ -f ".venv/bin/activate" ]; then
        source .venv/bin/activate
    elif [ -f ".venv/Scripts/activate" ]; then
        source .venv/Scripts/activate
    else
        print_error "Could not find virtual environment activation script"
        exit 1
    fi

    # Upgrade pip
    print_status "Upgrading pip..."
    python -m pip install --upgrade pip

    # Install dependencies
    print_status "Installing dependencies..."
    if [ -f "requirements.txt" ]; then
        pip install -r requirements.txt
    else
        pip install -e .
    fi

    # Install development dependencies if available
    if [ -f "requirements-dev.txt" ]; then
        pip install -r requirements-dev.txt
    elif grep -q "dev\]" pyproject.toml; then
        pip install -e ".[dev]"
    fi

    {% if cookiecutter.use_pre_commit == "yes" -%}
    # Install pre-commit hooks
    if command_exists pre-commit; then
        print_status "Installing pre-commit hooks..."
        pre-commit install
    fi
    {% endif -%}

    print_success "Project setup complete with pip!"
    print_status "Virtual environment created at .venv"
    print_status "To activate: source .venv/bin/activate (Linux/Mac) or .venv\\Scripts\\activate (Windows)"
}

# Setup with Pipenv
setup_with_pipenv() {
    print_status "Setting up project with Pipenv..."

    # Install Pipenv if not present
    if ! command_exists pipenv; then
        print_status "Installing Pipenv..."
        pip install pipenv
    fi

    # Install dependencies
    print_status "Installing dependencies..."
    pipenv install --dev

    {% if cookiecutter.use_pre_commit == "yes" -%}
    # Install pre-commit hooks
    print_status "Installing pre-commit hooks..."
    pipenv run pre-commit install
    {% endif -%}

    print_success "Project setup complete with Pipenv!"
    print_status "To activate the environment, run: pipenv shell"
    print_status "Or use Pipenv commands: pipenv run {{ cookiecutter.project_slug }} --help"
}

# Handle macOS/Linux permission issues
handle_permissions() {
    # Check if we're on macOS with externally-managed-environment
    if [[ "$OSTYPE" == "darwin"* ]]; then
        if $PYTHON_CMD -m pip install --help 2>&1 | grep -q "externally-managed-environment"; then
            print_warning "Detected macOS with externally-managed Python environment"
            print_status "Using virtual environment to avoid permission issues..."
            return 0
        fi
    fi

    # Check if we have write permissions to Python site-packages
    SITE_PACKAGES=$($PYTHON_CMD -c "import site; print(site.getsitepackages()[0])")
    if [ ! -w "$SITE_PACKAGES" ]; then
        print_warning "No write permission to system Python packages"
        print_status "Using virtual environment for safe installation..."
        return 0
    fi
}

# Main setup function
main() {
    print_status "{{ cookiecutter.project_name }} Setup Script"
    print_status "========================================"

    # Check Python version
    check_python_version

    # Handle permission issues
    handle_permissions

    # Determine package manager
    PACKAGE_MANAGER="{{ cookiecutter.package_manager }}"

    case $PACKAGE_MANAGER in
        "uv")
            install_uv
            setup_with_uv
            ;;
        "poetry")
            setup_with_poetry
            ;;
        "pipenv")
            setup_with_pipenv
            ;;
        "pip"|*)
            setup_with_pip
            ;;
    esac

    print_success "Setup completed successfully!"
    print_status ""
    print_status "Next steps:"
    print_status "1. Activate your virtual environment"
    print_status "2. Run: {{ cookiecutter.project_slug }} --help"
    {% if cookiecutter.use_testing == "yes" -%}
    print_status "3. Run tests: pytest"
    {% endif -%}
    {% if cookiecutter.use_linting == "yes" -%}
    print_status "4. Check code quality: ruff check && black --check ."
    {% endif -%}
}

# Run main function
main "$@"
