#!/bin/bash

# TUIkit CLI
# Modern command-line tool for creating TUIkit projects

set -e

VERSION="1.0.0"
TUIKIT_INSTALL_PATH="/usr/local/bin/tuikit"

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

# Uninstall tuikit
uninstall_tuikit() {
    echo -e "${YELLOW}Removing tuikit...${NC}"
    if [ -f "$TUIKIT_INSTALL_PATH" ]; then
        sudo rm -f "$TUIKIT_INSTALL_PATH" 2>/dev/null || rm -f "$TUIKIT_INSTALL_PATH"
    fi
    echo -e "${GREEN}tuikit has been removed.${NC}"
}

# Check if running on Linux and Swift is available
check_linux_swift() {
    # Only check on Linux
    if [ "$(uname)" != "Linux" ]; then
        return 0
    fi

    # Check if Swift is installed
    if command -v swift &> /dev/null; then
        return 0
    fi

    echo -e "${YELLOW}"
    echo "╔════════════════════════════════════════════════════╗"
    echo "║                                                    ║"
    echo "║       Swift is not installed on this system        ║"
    echo "║                                                    ║"
    echo "╚════════════════════════════════════════════════════╝"
    echo -e "${NC}"
    echo ""
    echo -e "TUIkit requires Swift 6.0 or later to create projects."
    echo ""
    echo -e "${YELLOW}Would you like to install Swift and its dependencies?${NC}"
    echo -e "This will install: Swift, clang, libcurl, and other required packages."
    echo ""
    read -p "Install Swift? [y/N] " -n 1 -r
    echo ""

    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        echo ""
        echo -e "${RED}Swift installation declined.${NC}"
        uninstall_tuikit
        echo -e "${YELLOW}Please install Swift manually from https://swift.org/download/${NC}"
        exit 1
    fi

    install_swift_linux
}

# Install Swift on Linux
install_swift_linux() {
    echo ""
    echo -e "${GREEN}Installing Swift and dependencies...${NC}"
    echo ""

    # Detect package manager and distribution
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        DISTRO=$ID
    else
        DISTRO="unknown"
    fi

    case "$DISTRO" in
        ubuntu|debian|linuxmint|pop)
            install_swift_debian
            ;;
        fedora|rhel|centos|rocky|almalinux)
            install_swift_fedora
            ;;
        arch|manjaro)
            install_swift_arch
            ;;
        *)
            install_swift_generic
            ;;
    esac

    # Verify installation
    if command -v swift &> /dev/null; then
        SWIFT_VERSION=$(swift --version 2>&1 | head -1)
        echo ""
        echo -e "${GREEN}Swift installed successfully!${NC}"
        echo -e "${BLUE}Version: ${NC}$SWIFT_VERSION"
        echo ""
    else
        echo ""
        echo -e "${RED}Swift installation failed.${NC}"
        echo -e "${YELLOW}Please install Swift manually from https://swift.org/download/${NC}"
        uninstall_tuikit
        exit 1
    fi
}

# Install Swift on Debian/Ubuntu
install_swift_debian() {
    echo -e "${BLUE}Detected Debian/Ubuntu-based system${NC}"
    echo ""

    # Install dependencies
    sudo apt-get update
    sudo apt-get install -y \
        binutils \
        git \
        gnupg2 \
        libc6-dev \
        libcurl4-openssl-dev \
        libedit2 \
        libgcc-11-dev \
        libpython3-dev \
        libsqlite3-0 \
        libstdc++-11-dev \
        libxml2-dev \
        libz3-dev \
        pkg-config \
        tzdata \
        unzip \
        zlib1g-dev \
        curl

    # Try to install Swift via swiftly (recommended method)
    if install_swift_via_swiftly; then
        return 0
    fi

    # Fallback: Try apt repository
    echo -e "${YELLOW}Trying Swift apt repository...${NC}"
    if curl -s https://archive.swiftlang.xyz/install.sh | sudo bash; then
        sudo apt-get update
        sudo apt-get install -y swiftlang
    else
        echo -e "${YELLOW}apt repository not available, downloading from swift.org...${NC}"
        install_swift_tarball
    fi
}

# Install Swift on Fedora/RHEL
install_swift_fedora() {
    echo -e "${BLUE}Detected Fedora/RHEL-based system${NC}"
    echo ""

    # Install dependencies
    sudo dnf install -y \
        binutils \
        gcc \
        git \
        glibc-static \
        gzip \
        libbsd \
        libcurl-devel \
        libedit \
        libicu \
        libstdc++-static \
        libuuid \
        libxml2-devel \
        sqlite \
        tar \
        tzdata \
        curl

    # Try swiftly first
    if install_swift_via_swiftly; then
        return 0
    fi

    # Fallback to tarball
    install_swift_tarball
}

# Install Swift on Arch Linux
install_swift_arch() {
    echo -e "${BLUE}Detected Arch-based system${NC}"
    echo ""

    # Swift is available in AUR
    if command -v yay &> /dev/null; then
        yay -S --noconfirm swift-bin
    elif command -v paru &> /dev/null; then
        paru -S --noconfirm swift-bin
    else
        echo -e "${YELLOW}No AUR helper found. Installing yay...${NC}"
        sudo pacman -S --needed --noconfirm git base-devel
        git clone https://aur.archlinux.org/yay.git /tmp/yay
        cd /tmp/yay && makepkg -si --noconfirm
        cd - > /dev/null
        yay -S --noconfirm swift-bin
    fi
}

# Install Swift via swiftly (cross-platform installer)
install_swift_via_swiftly() {
    echo -e "${BLUE}Installing Swift via swiftly...${NC}"

    if curl -L https://swiftlang.github.io/swiftly/swiftly-install.sh | bash -s -- -y; then
        # Source the environment
        if [ -f "$HOME/.local/share/swiftly/env.sh" ]; then
            source "$HOME/.local/share/swiftly/env.sh"
        fi
        # Install latest Swift
        "$HOME/.local/bin/swiftly" install latest
        return 0
    fi

    return 1
}

# Install Swift from official tarball (generic fallback)
install_swift_tarball() {
    echo -e "${BLUE}Downloading Swift from swift.org...${NC}"

    # Detect architecture
    ARCH=$(uname -m)
    case "$ARCH" in
        x86_64)
            SWIFT_ARCH="x86_64"
            ;;
        aarch64|arm64)
            SWIFT_ARCH="aarch64"
            ;;
        *)
            echo -e "${RED}Unsupported architecture: $ARCH${NC}"
            return 1
            ;;
    esac

    # Get Ubuntu version for tarball selection
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        UBUNTU_VERSION="${VERSION_ID}"
    else
        UBUNTU_VERSION="22.04"
    fi

    # Download and install (using Swift 6.0.2 as stable version)
    SWIFT_VERSION="6.0.2"
    SWIFT_RELEASE="swift-${SWIFT_VERSION}-RELEASE"
    SWIFT_PLATFORM="ubuntu${UBUNTU_VERSION}"

    DOWNLOAD_URL="https://download.swift.org/swift-${SWIFT_VERSION}-release/${SWIFT_PLATFORM//.}/${SWIFT_RELEASE}/${SWIFT_RELEASE}-${SWIFT_PLATFORM}-${SWIFT_ARCH}.tar.gz"

    echo -e "${BLUE}Downloading: ${NC}$DOWNLOAD_URL"

    TEMP_DIR=$(mktemp -d)
    curl -L "$DOWNLOAD_URL" -o "$TEMP_DIR/swift.tar.gz"

    echo -e "${BLUE}Extracting...${NC}"
    sudo mkdir -p /opt/swift
    sudo tar -xzf "$TEMP_DIR/swift.tar.gz" -C /opt/swift --strip-components=1

    # Add to PATH
    echo 'export PATH="/opt/swift/usr/bin:$PATH"' | sudo tee /etc/profile.d/swift.sh
    export PATH="/opt/swift/usr/bin:$PATH"

    rm -rf "$TEMP_DIR"
}

# Generic installation (fallback)
install_swift_generic() {
    echo -e "${YELLOW}Unknown Linux distribution.${NC}"
    echo -e "${BLUE}Attempting generic installation...${NC}"

    # Try swiftly first
    if install_swift_via_swiftly; then
        return 0
    fi

    # Fallback to tarball
    install_swift_tarball
}

# Help text
show_help() {
    echo -e "${GREEN}TUIkit CLI v${VERSION}${NC}"
    echo ""
    echo "Usage:"
    echo "  tuikit init [options] [project-name]"
    echo ""
    echo "Options:"
    echo "  git                 Initialize Git repository with initial commit"
    echo "  sqlite              Include GRDB for SQLite database storage"
    echo "  testing             Include Swift Testing framework"
    echo "  xctest              Include XCTest framework"
    echo ""
    echo "Examples:"
    echo "  tuikit init MyApp                    # Basic TUIkit app"
    echo "  tuikit init git MyApp                # With Git repository"
    echo "  tuikit init sqlite MyApp             # With SQLite"
    echo "  tuikit init testing MyApp            # With Swift Testing"
    echo "  tuikit init git sqlite testing MyApp # With Git, SQLite and Testing"
    echo ""
    echo "If no project name is provided, you'll be prompted to enter one."
}

# Check Linux Swift installation first
check_linux_swift

# Parse arguments
INIT_GIT=false
INCLUDE_SQLITE=false
TEST_FRAMEWORK="None"
PROJECT_NAME=""

if [ "$1" == "init" ]; then
    shift

    # Parse options and project name
    while [ $# -gt 0 ]; do
        case "$1" in
            git)
                INIT_GIT=true
                shift
                ;;
            sqlite)
                INCLUDE_SQLITE=true
                shift
                ;;
            testing)
                TEST_FRAMEWORK="Swift Testing"
                shift
                ;;
            xctest)
                TEST_FRAMEWORK="XCTest"
                shift
                ;;
            -h|--help)
                show_help
                exit 0
                ;;
            *)
                # Assume it's the project name
                PROJECT_NAME="$1"
                shift
                ;;
        esac
    done
else
    show_help
    exit 1
fi

# Prompt for project name if not provided
if [ -z "$PROJECT_NAME" ]; then
    echo -e "${YELLOW}Enter project name:${NC}"
    read -r PROJECT_NAME
fi

if [ -z "$PROJECT_NAME" ]; then
    echo -e "${RED}Error: Project name cannot be empty${NC}"
    exit 1
fi

# Banner with grayscale block style (like opencode)
show_banner() {
    # Grayscale ANSI colors (gradient from dark to light)
    local C1='\033[38;5;240m'  # Darkest (T)
    local C2='\033[38;5;244m'  # (U)
    local C3='\033[38;5;248m'  # (I)
    local C4='\033[38;5;252m'  # (k)
    local C5='\033[38;5;254m'  # (i)
    local C6='\033[38;5;255m'  # Brightest (t)
    local D='\033[38;5;236m'   # Dark inner
    local R='\033[0m'          # Reset

    echo ""
    # TUIkit in block letters with inner shadow effect
    echo -e "${C1}█${D}█${C1}█████${D}█${R}  ${C2}█${D}█${R}    ${C2}█${D}█${R}  ${C3}█${D}█${C3}█${R}  ${C4}█${D}█${R}  ${C4}█${D}█${R}  ${C5}█${D}█${R}  ${C6}█${D}█${C6}███${R}"
    echo -e "   ${C1}█${D}█${R}     ${C2}█${D}█${R}    ${C2}█${D}█${R}  ${C3}█${D}█${R}   ${C4}█${D}█${R} ${C4}█${D}█${R}   ${C5}█${D}█${R}   ${C6}█${D}█${R}"
    echo -e "   ${C1}█${D}█${R}     ${C2}█${D}█${R}    ${C2}█${D}█${R}  ${C3}█${D}█${R}   ${C4}█${D}█${C4}█${D}█${R}    ${C5}█${D}█${R}   ${C6}█${D}█${R}"
    echo -e "   ${C1}█${D}█${R}     ${C2}█${D}█${R}    ${C2}█${D}█${R}  ${C3}█${D}█${R}   ${C4}█${D}█${R} ${C4}█${D}█${R}   ${C5}█${D}█${R}   ${C6}█${D}█${R}"
    echo -e "   ${C1}█${D}█${R}      ${C2}█${D}█${C2}██${D}█${C2}█${R}   ${C3}█${D}█${C3}█${R}  ${C4}█${D}█${R}  ${C4}█${D}█${R}  ${C5}█${D}█${R}   ${C6}█${D}█${C6}█${R}"
    echo ""
}

show_banner

# Separate path and project name
# If PROJECT_NAME contains a path, extract the directory and basename
if [[ "$PROJECT_NAME" == *"/"* ]]; then
    # Expand ~ to home directory
    PROJECT_PATH="${PROJECT_NAME/#\~/$HOME}"
    PROJECT_BASE=$(basename "$PROJECT_PATH")
else
    PROJECT_PATH="$(pwd)/$PROJECT_NAME"
    PROJECT_BASE="$PROJECT_NAME"
fi

# Create project directory
echo -e "${GREEN}Creating project directory...${NC}"
mkdir -p "$PROJECT_PATH"
cd "$PROJECT_PATH"

# Use PROJECT_BASE for all file content (package name, etc.)
PROJECT_NAME="$PROJECT_BASE"

# Create Package.swift
echo -e "${GREEN}Creating Package.swift...${NC}"

# Build dependencies array
DEPENDENCIES="        .package(url: \"https://github.com/phranck/TUIkit.git\", branch: \"main\")"
if [ "$INCLUDE_SQLITE" = true ]; then
    DEPENDENCIES="${DEPENDENCIES},
        .package(url: \"https://github.com/groue/GRDB.swift.git\", from: \"7.0.0\")"
fi

# Build target dependencies
TARGET_DEPS="                .product(name: \"TUIkit\", package: \"TUIkit\")"
if [ "$INCLUDE_SQLITE" = true ]; then
    TARGET_DEPS="${TARGET_DEPS},
                .product(name: \"GRDB\", package: \"GRDB.swift\")"
fi

# Build targets array
TARGETS="        .executableTarget(
            name: \"${PROJECT_NAME}\",
            dependencies: [
${TARGET_DEPS}
            ],
            path: \"Sources\"
        )"

if [ "$TEST_FRAMEWORK" != "None" ]; then
    TARGETS="${TARGETS},
        .testTarget(
            name: \"${PROJECT_NAME}Tests\",
            dependencies: [\"${PROJECT_NAME}\"],
            path: \"Tests\"
        )"
fi

cat > Package.swift << EOF
// swift-tools-version: 6.0
import PackageDescription

let package = Package(
    name: "${PROJECT_NAME}",
    platforms: [.macOS(.v15)],
    dependencies: [
${DEPENDENCIES}
    ],
    targets: [
${TARGETS}
    ]
)
EOF

# Create Sources directory and files
echo -e "${GREEN}Creating source files...${NC}"
mkdir -p Sources

cat > Sources/App.swift << EOF
import TUIkit

@main
struct ${PROJECT_NAME}App: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
EOF

cat > Sources/ContentView.swift << 'EOF'
import TUIkit

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Hello, TUIkit!")
                .foregroundStyle(.palette.accent)
                .bold()

            Text("Welcome to your new terminal app")
                .foregroundStyle(.palette.foregroundSecondary)
        }
        .padding()
    }
}
EOF

# Create Database.swift if SQLite is enabled
if [ "$INCLUDE_SQLITE" = true ]; then
    cat > Sources/Database.swift << 'EOF'
import Foundation
import GRDB

/// Example model using GRDB
struct Item: Codable, FetchableRecord, PersistableRecord, Sendable {
    var id: Int64?
    var title: String
    var isCompleted: Bool

    // Define the database table
    static let databaseTableName = "items"
}

// MARK: - Database Setup

extension Item {
    /// Creates the items table
    static func createTable(in db: Database) throws {
        try db.create(table: databaseTableName, ifNotExists: true) { table in
            table.autoIncrementedPrimaryKey("id")
            table.column("title", .text).notNull()
            table.column("isCompleted", .boolean).notNull().defaults(to: false)
        }
    }
}
EOF
fi

# Create Tests if needed
if [ "$TEST_FRAMEWORK" != "None" ]; then
    echo -e "${BLUE}Creating test files...${NC}"
    mkdir -p Tests

    if [ "$TEST_FRAMEWORK" = "Swift Testing" ]; then
        cat > Tests/${PROJECT_NAME}Tests.swift << EOF
import Testing
@testable import $PROJECT_NAME

@Test func example() async throws {
    #expect(true)
}
EOF
    else
        cat > Tests/${PROJECT_NAME}Tests.swift << EOF
import XCTest
@testable import $PROJECT_NAME

final class ${PROJECT_NAME}Tests: XCTestCase {
    func testExample() throws {
        XCTAssertTrue(true)
    }
}
EOF
    fi
fi

# Create README.md
echo -e "${GREEN}Creating README.md...${NC}"
cat > README.md << EOF
# $PROJECT_NAME

A TUIkit terminal application.

## Quick Start

\`\`\`bash
swift run
\`\`\`

## Project Structure

\`\`\`
$PROJECT_NAME/
├── Sources/
│   ├── App.swift          # Main application entry point
│   └── ContentView.swift  # Root view
EOF

if [ "$INCLUDE_SQLITE" = true ]; then
    cat >> README.md << 'EOF'
│   └── Database.swift     # SQLite database helper
EOF
fi

if [ "$TEST_FRAMEWORK" != "None" ]; then
    cat >> README.md << EOF
└── Tests/                 # $TEST_FRAMEWORK suite
EOF
fi

cat >> README.md << 'EOF'
```

EOF

if [ "$INCLUDE_SQLITE" = true ]; then
    cat >> README.md << 'EOF'

## Database

This project includes [GRDB](https://github.com/groue/GRDB.swift) for local SQLite persistence.

**Quick Start:**

```swift
import GRDB

// Open database
let dbQueue = try DatabaseQueue(path: "db.sqlite")

// Create table
try dbQueue.write { db in
    try Item.createTable(in: db)
}

// Insert
try dbQueue.write { db in
    var item = Item(id: nil, title: "Task", isCompleted: false)
    try item.insert(db)
}

// Fetch all
let items = try dbQueue.read { db in
    try Item.fetchAll(db)
}
```

See [GRDB documentation](https://github.com/groue/GRDB.swift) for more details.

EOF
fi

cat >> README.md << 'EOF'

## Learn More

- [TUIkit Documentation](https://tuikit.layered.work/documentation/tuikit/)
- [TUIkit GitHub](https://github.com/phranck/TUIkit)
EOF

# Create .gitignore
cat > .gitignore << 'EOF'
.DS_Store
/.build
/Packages
xcuserdata/
DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
EOF

# Note: We don't create .swiftpm directory - Xcode generates it automatically
# and handles scheme/workspace settings better on its own

# Set Xcode preference for Swift packages to prefer macOS
defaults write com.apple.dt.Xcode IDEPackageSupportUseBuiltinSCM -bool YES 2>/dev/null || true
defaults write com.apple.dt.Xcode IDEPreferredPlatformForSwiftPackages -string "macosx" 2>/dev/null || true

# Initialize Git repository if requested
if [ "$INIT_GIT" = true ]; then
    echo -e "${GREEN}Initializing Git repository...${NC}"
    git init -q
    git add .
    git commit -q -m "Initial commit"
fi

# Success message
echo -e "${GREEN}"
echo "╔════════════════════════════════════════════════════╗"
echo "║                                                    ║"
echo "║            Project created successfully!           ║"
echo "║                                                    ║"
echo "╚════════════════════════════════════════════════════╝"
echo -e "${NC}"

echo -e "${BLUE}Project: ${NC}${GREEN}$PROJECT_NAME${NC}"
echo -e "${BLUE}Location: ${NC}$(pwd)"
echo -e "${BLUE}Git Repository: ${NC}$([ "$INIT_GIT" = true ] && echo "Yes" || echo "No")"
echo -e "${BLUE}Test Framework: ${NC}$TEST_FRAMEWORK"
echo -e "${BLUE}GRDB: ${NC}$([ "$INCLUDE_SQLITE" = true ] && echo "Yes" || echo "No")"

echo ""
read -p "Open project in Xcode? [Y/n] " -n 1 -r
echo ""

if [[ ! $REPLY =~ ^[Nn]$ ]]; then
    open "$PROJECT_PATH/Package.swift"
    echo -e "${GREEN}Opening in Xcode...${NC}"
    
    # Show macOS alert about deployment target (only on macOS)
    if [ "$(uname)" = "Darwin" ]; then
        echo ""
        echo -e "${YELLOW}╔════════════════════════════════════════════════════╗${NC}"
        echo -e "${YELLOW}║  IMPORTANT: Set Run Destination to \"My Mac\"        ║${NC}"
        echo -e "${YELLOW}║  in Xcode's toolbar before building!               ║${NC}"
        echo -e "${YELLOW}╚════════════════════════════════════════════════════╝${NC}"
    fi
else
    echo ""
    echo -e "${YELLOW}Next steps:${NC}"
    echo "  1. cd $PROJECT_PATH"
    echo "  2. open Package.swift"
    echo "  3. Set Run Destination to \"My Mac\" in Xcode"
    echo "  4. Wait for dependencies to resolve"
    echo "  5. Press Cmd+B to build"
fi
