#!/bin/bash

# ParentFlow Production Database Migration Script
# Runs all database migrations for both main app and admin dashboard

set -e

# Configuration
DB_HOST="10.0.0.207"
DB_PORT="5432"
DB_USER="postgres"
DB_PASSWORD="a3ppq"
DB_NAME="parentflow"
DB_NAME_ADMIN="parentflowadmin"

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

log() {
    echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
}

error() {
    echo -e "${RED}[ERROR]${NC} $1" >&2
    exit 1
}

success() {
    echo -e "${GREEN}✓${NC} $1"
}

warning() {
    echo -e "${YELLOW}⚠${NC} $1"
}

# Header
echo ""
echo "=========================================="
echo "   Database Migration for Production     "
echo "=========================================="
echo ""

# Check PostgreSQL client
if ! command -v psql &> /dev/null; then
    error "PostgreSQL client not installed. Run: apt-get install postgresql-client"
fi

# Test database connection
log "Testing database connection..."
PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d postgres -c "SELECT version();" > /dev/null 2>&1
if [ $? -ne 0 ]; then
    error "Cannot connect to database at $DB_HOST:$DB_PORT"
fi
success "Database connection successful"

# Create databases if they don't exist
log "Ensuring databases exist..."
PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d postgres << EOF
-- Create main database
SELECT 'CREATE DATABASE ${DB_NAME}'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '${DB_NAME}')\\gexec

-- Create admin database
SELECT 'CREATE DATABASE ${DB_NAME_ADMIN}'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '${DB_NAME_ADMIN}')\\gexec
EOF
success "Databases verified"

# Enable extensions
log "Enabling required extensions..."
PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -c "CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";"
PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -c "CREATE EXTENSION IF NOT EXISTS vector;"
PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME_ADMIN -c "CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";"
success "Extensions enabled"

# Find migration directory
MIGRATION_DIR="$(dirname "$0")/maternal-app/maternal-app-backend/src/database/migrations"
if [ ! -d "$MIGRATION_DIR" ]; then
    error "Migration directory not found: $MIGRATION_DIR"
fi

# Create migration tracking table
log "Creating migration tracking table..."
PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME << 'EOF'
CREATE TABLE IF NOT EXISTS schema_migrations (
    id SERIAL PRIMARY KEY,
    version VARCHAR(255) NOT NULL UNIQUE,
    executed_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    execution_time_ms INTEGER,
    success BOOLEAN DEFAULT true,
    error_message TEXT,
    checksum VARCHAR(64)
);

CREATE INDEX IF NOT EXISTS idx_schema_migrations_version ON schema_migrations(version);
CREATE INDEX IF NOT EXISTS idx_schema_migrations_executed ON schema_migrations(executed_at);
EOF
success "Migration tracking table ready"

# Define all migrations in order
MIGRATIONS=(
    "V001_create_core_auth.sql"
    "V002_create_family_structure.sql"
    "V003_create_child_entities.sql"
    "V004_create_activity_tables.sql"
    "V005_create_notification_system.sql"
    "V006_create_audit_log.sql"
    "V007_create_analytics_tables.sql"
    "V008_add_verification_system.sql"
    "V008_add_eula_fields.sql"
    "V009_add_family_preferences.sql"
    "V009_add_multi_child_preferences.sql"
    "V010_enhance_notifications.sql"
    "V010_add_ai_conversations.sql"
    "V011_add_tracking_enhancements.sql"
    "V011_create_photos_module.sql"
    "V012_add_device_registry.sql"
    "V013_add_mfa_support.sql"
    "V014_add_refresh_token_rotation.sql"
    "V015_add_audit_fields.sql"
    "V016_add_webauthn_support.sql"
    "V017_add_gdpr_compliance.sql"
    "V018_add_ai_embeddings.sql"
    "V019_add_voice_feedback.sql"
    "V020_add_indexes_optimization.sql"
    "V021_add_timezone_support.sql"
    "V022_add_data_archiving.sql"
    "V028_create_invite_codes.sql"
)

# Function to calculate file checksum
calculate_checksum() {
    local file=$1
    if command -v sha256sum &> /dev/null; then
        sha256sum "$file" | cut -d' ' -f1
    else
        echo "no-checksum"
    fi
}

# Run migrations
log "Running migrations for main database..."
TOTAL=${#MIGRATIONS[@]}
CURRENT=0
SKIPPED=0
EXECUTED=0

for migration in "${MIGRATIONS[@]}"; do
    CURRENT=$((CURRENT + 1))
    MIGRATION_FILE="$MIGRATION_DIR/$migration"

    if [ ! -f "$MIGRATION_FILE" ]; then
        warning "[$CURRENT/$TOTAL] Migration file not found: $migration"
        continue
    fi

    # Check if migration was already executed
    VERSION=$(echo $migration | cut -d'_' -f1)
    ALREADY_RUN=$(PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -tAc \
        "SELECT COUNT(*) FROM schema_migrations WHERE version = '$VERSION';")

    if [ "$ALREADY_RUN" = "1" ]; then
        echo -e "${YELLOW}[$CURRENT/$TOTAL]${NC} Skipping $migration (already applied)"
        SKIPPED=$((SKIPPED + 1))
        continue
    fi

    echo -e "${BLUE}[$CURRENT/$TOTAL]${NC} Applying $migration..."

    START_TIME=$(date +%s%3N)
    CHECKSUM=$(calculate_checksum "$MIGRATION_FILE")

    # Run migration
    if PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -f "$MIGRATION_FILE" > /dev/null 2>&1; then
        END_TIME=$(date +%s%3N)
        EXEC_TIME=$((END_TIME - START_TIME))

        # Record successful migration
        PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME << EOF
INSERT INTO schema_migrations (version, execution_time_ms, checksum)
VALUES ('$VERSION', $EXEC_TIME, '$CHECKSUM');
EOF
        success "Applied $migration (${EXEC_TIME}ms)"
        EXECUTED=$((EXECUTED + 1))
    else
        error "Failed to apply migration: $migration"
    fi
done

log "Migration summary: $EXECUTED executed, $SKIPPED skipped, $TOTAL total"

# Run admin-specific migrations if needed
log "Setting up admin database..."
PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME_ADMIN << 'EOF'
-- Admin users table (if not exists from main DB)
CREATE TABLE IF NOT EXISTS admin_users (
    id VARCHAR(36) PRIMARY KEY DEFAULT gen_random_uuid()::text,
    email VARCHAR(255) NOT NULL UNIQUE,
    password_hash VARCHAR(255) NOT NULL,
    name VARCHAR(100),
    role VARCHAR(50) DEFAULT 'admin',
    is_active BOOLEAN DEFAULT true,
    last_login_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    permissions JSONB DEFAULT '["users:read", "users:write", "invites:read", "invites:write", "analytics:read"]',
    two_factor_secret VARCHAR(255),
    two_factor_enabled BOOLEAN DEFAULT false
);

-- Admin sessions
CREATE TABLE IF NOT EXISTS admin_sessions (
    id VARCHAR(36) PRIMARY KEY DEFAULT gen_random_uuid()::text,
    admin_user_id VARCHAR(36) REFERENCES admin_users(id) ON DELETE CASCADE,
    token_hash VARCHAR(255) NOT NULL UNIQUE,
    ip_address VARCHAR(45),
    user_agent TEXT,
    expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    last_activity_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- Admin audit logs
CREATE TABLE IF NOT EXISTS admin_audit_logs (
    id VARCHAR(36) PRIMARY KEY DEFAULT gen_random_uuid()::text,
    admin_user_id VARCHAR(36) REFERENCES admin_users(id),
    action VARCHAR(100) NOT NULL,
    entity_type VARCHAR(50),
    entity_id VARCHAR(36),
    details JSONB DEFAULT '{}',
    ip_address VARCHAR(45),
    user_agent TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- Create indexes
CREATE INDEX IF NOT EXISTS idx_admin_users_email ON admin_users(email);
CREATE INDEX IF NOT EXISTS idx_admin_sessions_token ON admin_sessions(token_hash);
CREATE INDEX IF NOT EXISTS idx_admin_sessions_admin ON admin_sessions(admin_user_id);
CREATE INDEX IF NOT EXISTS idx_admin_audit_logs_admin ON admin_audit_logs(admin_user_id);
CREATE INDEX IF NOT EXISTS idx_admin_audit_logs_created ON admin_audit_logs(created_at);

-- Insert default admin user if not exists (password: admin123)
INSERT INTO admin_users (email, password_hash, name, role)
VALUES (
    'admin@parentflowapp.com',
    '$2b$10$H5hw3/iwkCichU5dpVIMqe5Me7WV9jz.qWRm0V4JyGF9smgxgFBxm',
    'System Administrator',
    'super_admin'
) ON CONFLICT (email) DO NOTHING;
EOF
success "Admin database configured"

# Verify migration status
log "Verifying migration status..."
TOTAL_APPLIED=$(PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -tAc \
    "SELECT COUNT(*) FROM schema_migrations WHERE success = true;")

echo ""
echo "=========================================="
echo -e "${GREEN}   Database Migration Completed!   ${NC}"
echo "=========================================="
echo ""
echo "Summary:"
echo "  Total migrations: $TOTAL"
echo "  Applied in this run: $EXECUTED"
echo "  Previously applied: $SKIPPED"
echo "  Total in database: $TOTAL_APPLIED"
echo ""
echo "Databases ready:"
echo "  Main: $DB_NAME at $DB_HOST:$DB_PORT"
echo "  Admin: $DB_NAME_ADMIN at $DB_HOST:$DB_PORT"
echo ""
success "All migrations completed successfully"