#!/bin/bash
# Comprehensive installation script for PunimTag Web
# Installs all system dependencies, Python packages, and frontend dependencies

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

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

echo -e "${BLUE}╔══════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║     PunimTag Web - Comprehensive Installation Script    ║${NC}"
echo -e "${BLUE}╚══════════════════════════════════════════════════════════╝${NC}"
echo ""

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

# Function to check Python version
check_python_version() {
    if command_exists python3; then
        PYTHON_VERSION=$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
        PYTHON_MAJOR=$(echo "$PYTHON_VERSION" | cut -d. -f1)
        PYTHON_MINOR=$(echo "$PYTHON_VERSION" | cut -d. -f2)
        
        if [ "$PYTHON_MAJOR" -lt 3 ] || ([ "$PYTHON_MAJOR" -eq 3 ] && [ "$PYTHON_MINOR" -lt 12 ]); then
            echo -e "${RED}❌ Python 3.12 or higher is required. Found: Python $PYTHON_VERSION${NC}"
            return 1
        else
            echo -e "${GREEN}✅ Python $PYTHON_VERSION found${NC}"
            return 0
        fi
    else
        echo -e "${RED}❌ Python 3 is not installed${NC}"
        return 1
    fi
}

# Function to check Node.js version
check_node_version() {
    if command_exists node; then
        NODE_VERSION=$(node -v | sed 's/v//')
        NODE_MAJOR=$(echo "$NODE_VERSION" | cut -d. -f1)
        
        if [ "$NODE_MAJOR" -lt 18 ]; then
            echo -e "${RED}❌ Node.js 18 or higher is required. Found: Node.js $NODE_VERSION${NC}"
            return 1
        else
            echo -e "${GREEN}✅ Node.js $NODE_VERSION found${NC}"
            return 0
        fi
    else
        echo -e "${RED}❌ Node.js is not installed${NC}"
        return 1
    fi
}

# Detect OS
detect_os() {
    if [[ "$OSTYPE" == "linux-gnu"* ]]; then
        if [ -f /etc/os-release ]; then
            . /etc/os-release
            OS=$ID
        else
            OS="linux"
        fi
    elif [[ "$OSTYPE" == "darwin"* ]]; then
        OS="macos"
    else
        OS="unknown"
    fi
    echo "$OS"
}

# Install system dependencies (Linux only)
install_system_dependencies() {
    local os=$(detect_os)
    
    if [[ "$os" != "ubuntu" && "$os" != "debian" ]]; then
        echo -e "${YELLOW}⚠️  Automatic system dependency installation is only supported on Ubuntu/Debian${NC}"
        echo -e "${YELLOW}   Please install PostgreSQL and Redis manually for other systems${NC}"
        return 0
    fi
    
    echo -e "${BLUE}📦 Installing system dependencies...${NC}"
    
    # Update package list
    sudo apt update
    
    # Install PostgreSQL
    if ! command_exists psql; then
        echo -e "${BLUE}   Installing PostgreSQL...${NC}"
        sudo apt install -y postgresql postgresql-contrib
        sudo systemctl start postgresql
        sudo systemctl enable postgresql
        echo -e "${GREEN}   ✅ PostgreSQL installed${NC}"
    else
        echo -e "${GREEN}   ✅ PostgreSQL already installed${NC}"
    fi
    
    # Install Redis
    if ! command_exists redis-cli; then
        echo -e "${BLUE}   Installing Redis...${NC}"
        sudo apt install -y redis-server
        sudo systemctl start redis-server
        sudo systemctl enable redis-server
        echo -e "${GREEN}   ✅ Redis installed${NC}"
    else
        echo -e "${GREEN}   ✅ Redis already installed${NC}"
    fi
    
    # Install Python tkinter (required for native folder picker)
    if ! python3 -c "import tkinter" 2>/dev/null; then
        echo -e "${BLUE}   Installing Python tkinter...${NC}"
        sudo apt install -y python3-tk
        echo -e "${GREEN}   ✅ Python tkinter installed${NC}"
    else
        echo -e "${GREEN}   ✅ Python tkinter already installed${NC}"
    fi
    
    # Verify Redis is running
    if redis-cli ping >/dev/null 2>&1; then
        echo -e "${GREEN}   ✅ Redis is running${NC}"
    else
        echo -e "${YELLOW}   ⚠️  Redis is not running. Starting Redis...${NC}"
        sudo systemctl start redis-server || redis-server --daemonize yes
    fi
}

# Setup PostgreSQL databases
setup_databases() {
    echo -e "${BLUE}🗄️  Setting up PostgreSQL databases...${NC}"
    
    if ! command_exists psql; then
        echo -e "${YELLOW}⚠️  PostgreSQL is not installed. Skipping database setup.${NC}"
        echo -e "${YELLOW}   Please install PostgreSQL and run: ./scripts/setup_postgresql.sh${NC}"
        return 0
    fi
    
    # Start PostgreSQL if not running
    if ! sudo systemctl is-active --quiet postgresql; then
        echo -e "${BLUE}   Starting PostgreSQL service...${NC}"
        sudo systemctl start postgresql
    fi
    
    # Create user and databases
    echo -e "${BLUE}   Creating database user and databases...${NC}"
    sudo -u postgres psql << 'EOF' || true
-- Create user if it doesn't exist
DO $$
BEGIN
    IF NOT EXISTS (SELECT FROM pg_user WHERE usename = 'punimtag') THEN
        CREATE USER punimtag WITH PASSWORD 'punimtag_password';
    END IF;
END
$$;

-- Create main database if it doesn't exist
SELECT 'CREATE DATABASE punimtag OWNER punimtag'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'punimtag')\gexec

-- Create auth database if it doesn't exist
SELECT 'CREATE DATABASE punimtag_auth OWNER punimtag'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'punimtag_auth')\gexec

-- Grant privileges
GRANT ALL PRIVILEGES ON DATABASE punimtag TO punimtag;
GRANT ALL PRIVILEGES ON DATABASE punimtag_auth TO punimtag;
\q
EOF
    
    echo -e "${GREEN}   ✅ Databases created${NC}"
}

# Create Python virtual environment
setup_python_venv() {
    echo -e "${BLUE}🐍 Setting up Python virtual environment...${NC}"
    
    if [ ! -d "venv" ]; then
        echo -e "${BLUE}   Creating virtual environment...${NC}"
        python3 -m venv venv
        echo -e "${GREEN}   ✅ Virtual environment created${NC}"
    else
        echo -e "${GREEN}   ✅ Virtual environment already exists${NC}"
    fi
    
    # Activate virtual environment
    source venv/bin/activate
    
    # Upgrade pip
    echo -e "${BLUE}   Upgrading pip...${NC}"
    pip install --upgrade pip --quiet
    
    echo -e "${GREEN}   ✅ Python environment ready${NC}"
}

# Install Python dependencies
install_python_dependencies() {
    echo -e "${BLUE}📦 Installing Python dependencies...${NC}"
    
    if [ ! -f "requirements.txt" ]; then
        echo -e "${RED}❌ requirements.txt not found${NC}"
        return 1
    fi
    
    source venv/bin/activate
    pip install -r requirements.txt
    
    echo -e "${GREEN}   ✅ Python dependencies installed${NC}"
}

# Download DeepFace model weights (optional, but recommended)
download_deepface_models() {
    echo -e "${BLUE}🤖 Downloading DeepFace model weights (optional)...${NC}"
    
    source venv/bin/activate
    
    # Check if deepface is installed
    if ! python3 -c "import deepface" 2>/dev/null; then
        echo -e "${YELLOW}   ⚠️  DeepFace not installed, skipping model download${NC}"
        return 0
    fi
    
    # Create weights directory
    mkdir -p ~/.deepface/weights
    
    # Check if ArcFace weights already exist
    if [ -f ~/.deepface/weights/arcface_weights.h5 ]; then
        echo -e "${GREEN}   ✅ ArcFace model weights already exist${NC}"
        return 0
    fi
    
    echo -e "${BLUE}   Downloading ArcFace model weights (~131MB, this may take a few minutes)...${NC}"
    
    # Try to download using wget (more reliable than Python download in worker)
    if command_exists wget; then
        if wget -q --show-progress \
            https://github.com/serengil/deepface_models/releases/download/v1.0/arcface_weights.h5 \
            -O ~/.deepface/weights/arcface_weights.h5; then
            echo -e "${GREEN}   ✅ ArcFace model weights downloaded successfully${NC}"
            return 0
        fi
    fi
    
    # Fallback: try with Python (may fail in some environments)
    echo -e "${YELLOW}   ⚠️  wget failed, trying Python download...${NC}"
    if python3 << 'PYTHON'
import os
import sys
from pathlib import Path

try:
    from deepface import DeepFace
    import numpy as np
    from PIL import Image
    
    # Create a dummy image to trigger model download
    dummy_img = Image.new('RGB', (100, 100), color='black')
    dummy_array = np.array(dummy_img)
    
    # This will trigger model download
    try:
        DeepFace.represent(
            img_path=dummy_array,
            model_name="ArcFace",
            detector_backend="retinaface",
            enforce_detection=False,
            align=True,
        )
        print("✅ Model weights downloaded successfully")
        sys.exit(0)
    except Exception as e:
        if "arcface_weights" in str(e).lower():
            print(f"⚠️  Download failed: {e}")
            print("   You can download manually later or the worker will try again")
            sys.exit(1)
        # Other errors are OK (like no faces found)
        print("✅ Model weights are available")
        sys.exit(0)
except ImportError:
    print("⚠️  DeepFace not available")
    sys.exit(0)
except Exception as e:
    print(f"⚠️  Error: {e}")
    sys.exit(1)
PYTHON
    then
        echo -e "${GREEN}   ✅ DeepFace models ready${NC}"
    else
        echo -e "${YELLOW}   ⚠️  Automatic download failed. Models will be downloaded on first use.${NC}"
        echo -e "${YELLOW}   ⚠️  To download manually, run:${NC}"
        echo -e "${BLUE}      mkdir -p ~/.deepface/weights${NC}"
        echo -e "${BLUE}      wget https://github.com/serengil/deepface_models/releases/download/v1.0/arcface_weights.h5 -O ~/.deepface/weights/arcface_weights.h5${NC}"
    fi
}

# Install frontend dependencies
install_frontend_dependencies() {
    echo -e "${BLUE}📦 Installing frontend dependencies...${NC}"
    
    # Install admin frontend
    if [ -d "admin-frontend" ]; then
        echo -e "${BLUE}   Installing admin frontend dependencies...${NC}"
        cd admin-frontend
        if [ -f "package.json" ]; then
            npm install
            echo -e "${GREEN}   ✅ Admin frontend dependencies installed${NC}"
        fi
        cd ..
    fi
    
    # Install viewer frontend
    if [ -d "viewer-frontend" ]; then
        echo -e "${BLUE}   Installing viewer frontend dependencies...${NC}"
        cd viewer-frontend
        if [ -f "package.json" ]; then
            npm install
            echo -e "${GREEN}   ✅ Viewer frontend dependencies installed${NC}"
        fi
        cd ..
    fi
}

# Create .env file if it doesn't exist
create_env_file() {
    echo -e "${BLUE}⚙️  Setting up environment configuration...${NC}"
    
    if [ ! -f ".env" ]; then
        echo -e "${BLUE}   Creating .env file...${NC}"
        cat > .env << 'EOF'
# Database (PostgreSQL by default)
DATABASE_URL=postgresql+psycopg2://punimtag:punimtag_password@localhost:5432/punimtag

# Auth Database (for frontend website user accounts - separate from main database)
DATABASE_URL_AUTH=postgresql+psycopg2://punimtag:punimtag_password@localhost:5432/punimtag_auth

# JWT Secrets (change in production!)
SECRET_KEY=dev-secret-key-change-in-production

# Single-user credentials (change in production!)
ADMIN_USERNAME=admin
ADMIN_PASSWORD=admin

# Photo storage directory (default: data/uploads)
PHOTO_STORAGE_DIR=data/uploads
EOF
        echo -e "${GREEN}   ✅ .env file created${NC}"
        echo -e "${YELLOW}   ⚠️  Please review and update .env file with your configuration${NC}"
    else
        echo -e "${GREEN}   ✅ .env file already exists${NC}"
    fi
    
    # Create admin frontend .env file if it doesn't exist
    if [ -d "admin-frontend" ] && [ ! -f "admin-frontend/.env" ]; then
        echo -e "${BLUE}   Creating admin-frontend/.env file...${NC}"
        cat > admin-frontend/.env << 'EOF'
# Backend API URL (must be accessible from browsers)
VITE_API_URL=http://127.0.0.1:8000
EOF
        echo -e "${GREEN}   ✅ admin-frontend/.env file created${NC}"
    elif [ -d "admin-frontend" ]; then
        echo -e "${GREEN}   ✅ admin-frontend/.env file already exists${NC}"
    fi
    
    # Create viewer frontend .env file if it doesn't exist
    if [ -d "viewer-frontend" ] && [ ! -f "viewer-frontend/.env.local" ]; then
        echo -e "${BLUE}   Creating viewer-frontend/.env.local file...${NC}"
        cat > viewer-frontend/.env.local << 'EOF'
# Database connection (read-only recommended)
DATABASE_URL=postgresql://punimtag:punimtag_password@localhost:5432/punimtag

# Auth database connection
DATABASE_URL_AUTH=postgresql://punimtag:punimtag_password@localhost:5432/punimtag_auth

# NextAuth configuration
NEXTAUTH_URL=http://localhost:3001
NEXTAUTH_SECRET=dev-secret-key-change-in-production
EOF
        echo -e "${GREEN}   ✅ viewer-frontend/.env.local file created${NC}"
    elif [ -d "viewer-frontend" ]; then
        echo -e "${GREEN}   ✅ viewer-frontend/.env.local file already exists${NC}"
    fi
}

# Create data directories
create_data_directories() {
    echo -e "${BLUE}📁 Creating data directories...${NC}"
    
    mkdir -p data/uploads
    mkdir -p data/thumbnails
    
    echo -e "${GREEN}   ✅ Data directories created${NC}"
}

# Main installation function
main() {
    echo -e "${BLUE}🔍 Checking prerequisites...${NC}"
    echo ""
    
    # Check Python
    if ! check_python_version; then
        echo -e "${RED}❌ Please install Python 3.12 or higher${NC}"
        exit 1
    fi
    
    # Check Node.js
    if ! check_node_version; then
        echo -e "${RED}❌ Please install Node.js 18 or higher${NC}"
        exit 1
    fi
    
    # Check npm
    if ! command_exists npm; then
        echo -e "${RED}❌ npm is not installed${NC}"
        exit 1
    else
        echo -e "${GREEN}✅ npm found${NC}"
    fi
    
    echo ""
    echo -e "${BLUE}🚀 Starting installation...${NC}"
    echo ""
    
    # Install system dependencies (Linux only)
    install_system_dependencies
    echo ""
    
    # Setup databases
    setup_databases
    echo ""
    
    # Setup Python environment
    setup_python_venv
    echo ""
    
    # Install Python dependencies
    install_python_dependencies
    echo ""
    
    # Download DeepFace model weights (optional)
    download_deepface_models
    echo ""
    
    # Install frontend dependencies
    install_frontend_dependencies
    echo ""
    
    # Create .env files
    create_env_file
    echo ""
    
    # Create data directories
    create_data_directories
    echo ""
    
    # Success message
    echo -e "${GREEN}╔══════════════════════════════════════════════════════════╗${NC}"
    echo -e "${GREEN}║           ✅ Installation Complete!                       ║${NC}"
    echo -e "${GREEN}╚══════════════════════════════════════════════════════════╝${NC}"
    echo ""
    echo -e "${BLUE}📋 Next Steps:${NC}"
    echo ""
    echo -e "1. ${YELLOW}Review and update .env file${NC} (if needed):"
    echo -e "   ${BLUE}   nano .env${NC}"
    echo ""
    echo -e "2. ${YELLOW}Activate the virtual environment:${NC}"
    echo -e "   ${BLUE}   source venv/bin/activate${NC}"
    echo ""
    echo -e "3. ${YELLOW}Start the backend API:${NC}"
    echo -e "   ${BLUE}   export PYTHONPATH=$PROJECT_ROOT${NC}"
    echo -e "   ${BLUE}   uvicorn backend.app:app --host 127.0.0.1 --port 8000${NC}"
    echo ""
    echo -e "4. ${YELLOW}In another terminal, start the admin frontend:${NC}"
    echo -e "   ${BLUE}   cd admin-frontend${NC}"
    echo -e "   ${BLUE}   npm run dev${NC}"
    echo ""
    echo -e "5. ${YELLOW}In another terminal, start the viewer frontend (optional):${NC}"
    echo -e "   ${BLUE}   cd viewer-frontend${NC}"
    echo -e "   ${BLUE}   npm run dev${NC}"
    echo ""
    echo -e "6. ${YELLOW}Access the applications:${NC}"
    echo -e "   ${BLUE}   Admin: http://localhost:3000${NC}"
    echo -e "   ${BLUE}   Viewer: http://localhost:3001${NC}"
    echo ""
    echo -e "${GREEN}For more information, see README.md${NC}"
    echo ""
}

# Run main function
main

