#!/usr/bin/env bash
set -e

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

BACKEND_PATH="${1:-./tina-backend}"

log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

print_usage() {
    cat << EOF
Usage: $(basename "$0") [target-path]

Install Tina CMS Backend (self-hosted)

Arguments:
  target-path    Path where Tina backend will be installed (default: ./tina-backend)

Examples:
  $(basename "$0") /opt/tina-backend

This script installs a self-hosted Tina CMS backend with:
  - Auth.js authentication
  - SQLite database adapter
  - Git provider for content
  - Next.js API routes

Requirements:
  - Node.js 18+
  - npm or yarn
  - git

EOF
}

main() {
    echo "=============================================="
    echo "  Tina CMS Backend Installer (Self-Hosted)"
    echo "=============================================="
    echo ""

    if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
        print_usage
        exit 0
    fi

    if [ -d "$BACKEND_PATH" ]; then
        log_error "Directory already exists: $BACKEND_PATH"
        exit 1
    fi

    log_info "Creating Tina backend at: $BACKEND_PATH"
    mkdir -p "$BACKEND_PATH"
    cd "$BACKEND_PATH"

    log_info "Creating package.json..."
    cat > package.json << 'PKGEOF'
{
  "name": "tina-backend",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "dev": "tinacms dev",
    "build": "tinacms build",
    "start": "tinacms start"
  },
  "dependencies": {
    "@auth/core": "^0.34.0",
    "@auth/drizzle-adapter": "^1.4.0",
    "@libsql/client": "^0.14.0",
    "@tinacms/auth": "^2.0.0",
    "@tinacms/database": "^2.0.0",
    "@tinacms/git-provider": "^2.0.0",
    "@tinacms/graphql": "^2.0.0",
    "@tinacms/mssql": "^2.0.0",
    "@tinacms/server": "^2.0.0",
    "drizzle-orm": "^0.38.0",
    "next": "^14.0.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0",
    "tinacms": "^2.0.0"
  },
  "devDependencies": {
    "@types/node": "^20.0.0",
    "typescript": "^5.0.0"
  }
}
PKGEOF

    log_info "Creating TypeScript config..."
    cat > tsconfig.json << 'TSEOF'
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "jsx": "react-jsx"
  },
  "include": ["src/**/*", "tina/**/*"],
  "exclude": ["node_modules"]
}
TSEOF

    mkdir -p src/app/api/auth/\[...nextauth\]
    mkdir -p src/app/api/tina/\[\[...tina\]\]
    mkdir -p tina

    log_info "Creating Auth.js configuration..."
    cat > src/auth.config.ts << 'AUTHEOF'
import { AuthConfig } from "@auth/core/types";

const authConfig: AuthConfig = {
  secret: process.env.NEXTAUTH_SECRET || "your-secret-change-in-production",
  providers: [
    {
      id: "github",
      name: "GitHub",
      type: "oauth",
      clientId: process.env.GITHUB_ID || "",
      clientSecret: process.env.GITHUB_SECRET || "",
    },
  ],
  callbacks: {
    async session({ session, token }) {
      if (session.user && token.sub) {
        session.user.email = token.email as string;
      }
      return session;
    },
  },
  pages: {
    signIn: "/auth/signin",
  },
};

export default authConfig;
AUTHEOF

    log_info "Creating NextAuth API route..."
    cat > 'src/app/api/auth/[...nextauth]/route.ts' << 'NEXTAUTHEOF'
import { NextRequest, NextResponse } from "next/server";
import { AuthHandler } from "@auth/core";
import authConfig from "../../../auth.config";

const authHandler = (req: NextRequest) =>
  AuthHandler({
    ...authConfig,
    req: req as any,
    resolve(): Promise<any> {
      throw new Error("Function not implemented.");
    },
    secret: authConfig.secret!,
    trustHost: true,
  });

export { authHandler as GET, authHandler as POST };
NEXTAUTHEOF

    log_info "Creating Tina API route..."
    cat > 'src/app/api/tina/[[...tina]]/route.ts' << 'TINAEOF'
import { TinaNodeBackend } from "@tinacms/server";
import authConfig from "../../../../auth.config";
import { branchName } from "./branch";

const tinaBackend = TinaNodeBackend({
  authConfig: authConfig as any,
  branch: branchName,
});

export { tinaBackend as GET, tinaBackend as POST };
TINAEOF

    log_info "Creating Tina branch configuration..."
    cat > src/app/api/tina/branch.ts << 'BRANCHEMAP'
export const branchName = process.env.TINA_BRANCH || "main";
BRANCHEMAP

    log_info "Creating database schema..."
    mkdir -p src/lib
    cat > src/lib/schema.ts << 'DBEOF'
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";

export const users = sqliteTable("users", {
  id: text("id").primaryKey(),
  name: text("name"),
  email: text("email").unique(),
  emailVerified: integer("email_verified", { mode: "boolean" }),
  image: text("image"),
  createdAt: integer("created_at", { mode: "timestamp" }),
  updatedAt: integer("updated_at", { mode: "timestamp" }),
});

export const accounts = sqliteTable("accounts", {
  id: text("id").primaryKey(),
  userId: text("user_id")
    .references(() => users.id)
    .notNull(),
  type: text("type").notNull(),
  provider: text("provider").notNull(),
  providerAccountId: text("provider_account_id").notNull(),
  refresh_token: text("refresh_token"),
  access_token: text("access_token"),
  expires_at: integer("expires_at"),
  token_type: text("token_type"),
  scope: text("scope"),
  id_token: text("id_token"),
  session_state: text("session_state"),
});

export const sessions = sqliteTable("sessions", {
  id: text("id").primaryKey(),
  sessionToken: text("session_token").unique(),
  userId: text("user_id")
    .references(() => users.id)
    .notNull(),
  expires: integer("expires", { mode: "timestamp" }).notNull(),
});

export const verificationTokens = sqliteTable("verification_tokens", {
  identifier: text("identifier").notNull(),
  token: text("token").notNull(),
  expires: integer("expires", { mode: "timestamp" }).notNull(),
});
DBEOF

    log_info "Creating database client..."
    cat > src/lib/db.ts << 'DBCEOF'
import { createClient } from "@libsql/client";
import { drizzle } from "drizzle-orm/libsql";
import * as schema from "./schema";

const client = createClient({
  url: process.env.DATABASE_URL || "file:local.db",
});

export const db = drizzle(client, { schema });
DBCEOF

    log_info "Creating environment template..."
    cat > .env.example << 'ENVEOF'
NEXTAUTH_SECRET=generate-a-random-secret-here
NEXTAUTH_URL=http://localhost:3000

GITHUB_ID=your-github-oauth-app-client-id
GITHUB_SECRET=your-github-oauth-app-client-secret

DATABASE_URL=file:local.db
TINA_BRANCH=main
ENVEOF

    log_info "Creating README..."
    cat > README.md << 'READMEEOF'
# Tina CMS Backend (Self-Hosted)

Self-hosted Tina CMS backend with Auth.js authentication and SQLite database.

## Setup

1. Install dependencies:
   ```bash
   npm install
   ```

2. Configure environment:
   ```bash
   cp .env.example .env
   # Edit .env with your settings
   ```

3. Set up GitHub OAuth App:
   - Go to https://github.com/settings/developers
   - Create a new OAuth App
   - Set callback URL to: `http://your-domain.com/api/auth/callback/github`

4. Start development:
   ```bash
   npm run dev
   ```

## Environment Variables

| Variable | Description |
|----------|-------------|
| NEXTAUTH_SECRET | Random secret for NextAuth |
| NEXTAUTH_URL | Your site URL |
| GITHUB_ID | GitHub OAuth Client ID |
| GITHUB_SECRET | GitHub OAuth Client Secret |
| DATABASE_URL | SQLite database path |
| TINA_BRANCH | Git branch for content |

## Connecting Frontend

In your Astro frontend's `tina/config.ts`:

```ts
import { defineConfig } from "tinacms";

export default defineConfig({
  apiUrl: "https://your-tina-backend.com",
  contentApiUrl: "https://your-tina-backend.com",
});
```
READMEEOF

    log_success "Tina backend created at: $BACKEND_PATH"
    echo ""
    echo "Next steps:"
    echo "  1. cd $BACKEND_PATH"
    echo "  2. npm install"
    echo "  3. cp .env.example .env"
    echo "  4. Configure GitHub OAuth App"
    echo "  5. npm run dev"
    echo ""
}

main "$@"