#!/bin/bash

# Database Setup Script
# Provides convenient commands for database management

set -e

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

# Script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname $(dirname "$SCRIPT_DIR"))"

# Change to project root
cd "$PROJECT_ROOT"

# Logging functions
log() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

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

print_header() {
    echo -e "${BLUE}=== $1 ===${NC}"
}

print_usage() {
    echo "Database Setup Script"
    echo
    echo "Usage: $0 <command> [options]"
    echo
    echo "Commands:"
    echo "  setup               Full database setup (create + migrate + seed)"
    echo "  create              Create the database"
    echo "  migrate             Run migrations"
    echo "  seed                Seed database with test data"
    echo "  reset               Reset database (drop + create + migrate)"
    echo "  status              Show migration status"
    echo "  drop                Drop the database"
    echo "  postgres            Setup PostgreSQL database"
    echo "  sqlite              Setup SQLite database"
    echo
    echo "Options:"
    echo "  --env ENV           Environment (dev/prod) [default: dev]"
    echo "  --force             Skip confirmations"
    echo "  --quiet             Suppress verbose output"
    echo
    echo "Examples:"
    echo "  $0 setup            # Full setup with default settings"
    echo "  $0 migrate          # Run pending migrations"
    echo "  $0 reset --force    # Reset database without confirmation"
    echo "  $0 postgres         # Setup PostgreSQL specifically"
    echo "  $0 sqlite           # Setup SQLite specifically"
}

# Check if .env file exists
check_env_file() {
    if [ ! -f ".env" ]; then
        log_warn ".env file not found"
        log "Creating .env file from template..."

        if [ -f ".env.example" ]; then
            cp ".env.example" ".env"
            log "Created .env from .env.example"
        else
            create_default_env
        fi
    fi
}

# Create default .env file
create_default_env() {
    cat > ".env" << EOF
# Environment Configuration
ENVIRONMENT=dev

# Database Configuration
DATABASE_URL=postgresql://dev:dev@localhost:5432/rustelo_dev

# Server Configuration
SERVER_HOST=127.0.0.1
SERVER_PORT=3030
SERVER_PROTOCOL=http

# Session Configuration
SESSION_SECRET=dev-secret-not-for-production

# Features
ENABLE_AUTH=true
ENABLE_CONTENT_DB=true
ENABLE_TLS=false

# Logging
LOG_LEVEL=debug
RUST_LOG=debug
EOF
    log "Created default .env file"
}

# Check dependencies
check_dependencies() {
    local missing=()

    if ! command -v cargo >/dev/null 2>&1; then
        missing+=("cargo (Rust)")
    fi

    if ! command -v psql >/dev/null 2>&1 && ! command -v sqlite3 >/dev/null 2>&1; then
        missing+=("psql (PostgreSQL) or sqlite3")
    fi

    if [ ${#missing[@]} -gt 0 ]; then
        log_error "Missing dependencies: ${missing[*]}"
        echo
        echo "Please install the missing dependencies:"
        echo "- Rust: https://rustup.rs/"
        echo "- PostgreSQL: https://postgresql.org/download/"
        echo "- SQLite: Usually pre-installed or via package manager"
        exit 1
    fi
}

# Setup PostgreSQL database
setup_postgresql() {
    print_header "Setting up PostgreSQL Database"

    # Check if PostgreSQL is running
    if ! pg_isready >/dev/null 2>&1; then
        log_warn "PostgreSQL is not running"
        echo "Please start PostgreSQL service:"
        echo "  macOS (Homebrew): brew services start postgresql"
        echo "  Linux (systemd): sudo systemctl start postgresql"
        echo "  Windows: Start PostgreSQL service from Services panel"
        exit 1
    fi

    # Create development user if it doesn't exist
    if ! psql -U postgres -tc "SELECT 1 FROM pg_user WHERE usename = 'dev'" | grep -q 1; then
        log "Creating development user..."
        psql -U postgres -c "CREATE USER dev WITH PASSWORD 'dev' CREATEDB;"
    fi

    # Update DATABASE_URL in .env
    if grep -q "sqlite://" .env; then
        log "Updating .env to use PostgreSQL..."
        sed -i.bak 's|DATABASE_URL=.*|DATABASE_URL=postgresql://dev:dev@localhost:5432/rustelo_dev|' .env
        rm -f .env.bak
    fi

    log "PostgreSQL setup complete"
}

# Setup SQLite database
setup_sqlite() {
    print_header "Setting up SQLite Database"

    # Create data directory
    mkdir -p data

    # Update DATABASE_URL in .env
    if grep -q "postgresql://" .env; then
        log "Updating .env to use SQLite..."
        sed -i.bak 's|DATABASE_URL=.*|DATABASE_URL=sqlite://data/rustelo.db|' .env
        rm -f .env.bak
    fi

    log "SQLite setup complete"
}

# Run database tool command
run_db_tool() {
    local command="$1"
    log "Running: cargo run --bin db_tool -- $command"

    if [ "$QUIET" = "true" ]; then
        cargo run --bin db_tool -- "$command" >/dev/null 2>&1
    else
        cargo run --bin db_tool -- "$command"
    fi
}

# Create seed directory and files if they don't exist
setup_seeds() {
    if [ ! -d "seeds" ]; then
        log "Creating seeds directory..."
        mkdir -p seeds

        # Create sample seed files
        cat > "seeds/001_sample_users.sql" << EOF
-- Sample users for development
-- This file works for both PostgreSQL and SQLite

INSERT INTO users (username, email, password_hash, is_active, is_verified) VALUES
('admin', 'admin@example.com', '\$argon2id\$v=19\$m=65536,t=3,p=4\$Ym9vZm9v\$2RmTUplMXB3YUNGeFczL1NyTlJFWERsZVdrbUVuNHhDNlk5K1ZZWVorUT0', true, true),
('user', 'user@example.com', '\$argon2id\$v=19\$m=65536,t=3,p=4\$Ym9vZm9v\$2RmTUplMXB3YUNGeFczL1NyTlJFWERsZVdrbUVuNHhDNlk5K1ZZWVorUT0', true, true),
('editor', 'editor@example.com', '\$argon2id\$v=19\$m=65536,t=3,p=4\$Ym9vZm9v\$2RmTUplMXB3YUNGeFczL1NyTlJFWERsZVdrbUVuNHhDNlk5K1ZZWVorUT0', true, true)
ON CONFLICT (email) DO NOTHING;
EOF

        cat > "seeds/002_sample_content.sql" << EOF
-- Sample content for development
-- This file works for both PostgreSQL and SQLite

INSERT INTO content (title, slug, content_type, body, is_published, published_at) VALUES
('Welcome to Rustelo', 'welcome', 'markdown', '# Welcome to Rustelo

This is a sample content page created by the seed data.

## Features

- Fast and secure
- Built with Rust
- Modern web framework
- Easy to use

Enjoy building with Rustelo!', true, CURRENT_TIMESTAMP),

('About Us', 'about', 'markdown', '# About Us

This is the about page for your Rustelo application.

You can edit this content through the admin interface or by modifying the seed files.', true, CURRENT_TIMESTAMP),

('Getting Started', 'getting-started', 'markdown', '# Getting Started

Here are some tips to get you started with your new Rustelo application:

1. Check out the admin interface
2. Create your first content
3. Customize the design
4. Deploy to production

Good luck!', false, NULL)
ON CONFLICT (slug) DO NOTHING;
EOF

        log "Created sample seed files"
    fi
}

# Main setup function
full_setup() {
    print_header "Full Database Setup"

    check_env_file
    setup_seeds

    log "Creating database..."
    run_db_tool "create"

    log "Running migrations..."
    run_db_tool "migrate"

    log "Seeding database..."
    run_db_tool "seed"

    log "Checking status..."
    run_db_tool "status"

    print_header "Setup Complete!"
    log "Database is ready for development"
    echo
    log "Next steps:"
    echo "  1. Start the server: cargo leptos watch"
    echo "  2. Open http://localhost:3030 in your browser"
    echo "  3. Check the database status: $0 status"
}

# Parse command line arguments
COMMAND=""
ENVIRONMENT="dev"
FORCE=false
QUIET=false

while [[ $# -gt 0 ]]; do
    case $1 in
        --env)
            ENVIRONMENT="$2"
            shift 2
            ;;
        --force)
            FORCE=true
            shift
            ;;
        --quiet)
            QUIET=true
            shift
            ;;
        -h|--help)
            print_usage
            exit 0
            ;;
        *)
            if [ -z "$COMMAND" ]; then
                COMMAND="$1"
            else
                log_error "Unknown option: $1"
                print_usage
                exit 1
            fi
            shift
            ;;
    esac
done

# Set environment variable
export ENVIRONMENT="$ENVIRONMENT"

# Validate command
if [ -z "$COMMAND" ]; then
    print_usage
    exit 1
fi

# Check dependencies
check_dependencies

# Check if we're in the right directory
if [ ! -f "Cargo.toml" ]; then
    log_error "Please run this script from the project root directory"
    exit 1
fi

# Execute command
case "$COMMAND" in
    "setup")
        full_setup
        ;;
    "create")
        print_header "Creating Database"
        check_env_file
        run_db_tool "create"
        ;;
    "migrate")
        print_header "Running Migrations"
        run_db_tool "migrate"
        ;;
    "seed")
        print_header "Seeding Database"
        setup_seeds
        run_db_tool "seed"
        ;;
    "reset")
        print_header "Resetting Database"
        if [ "$FORCE" != "true" ]; then
            echo -n "This will destroy all data. Are you sure? (y/N): "
            read -r confirm
            if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
                log "Reset cancelled"
                exit 0
            fi
        fi
        run_db_tool "reset"
        ;;
    "status")
        print_header "Database Status"
        run_db_tool "status"
        ;;
    "drop")
        print_header "Dropping Database"
        run_db_tool "drop"
        ;;
    "postgres")
        setup_postgresql
        full_setup
        ;;
    "sqlite")
        setup_sqlite
        full_setup
        ;;
    *)
        log_error "Unknown command: $COMMAND"
        print_usage
        exit 1
        ;;
esac
