import { existsSync, mkdirSync, writeFileSync } from "fs";
import { join, resolve } from "path";
import pc from "picocolors";
export async function init(options) {
    const targetPath = resolve(options?.path || ".");
    const quickbackPath = join(targetPath, "quickback");
    // Check if quickback folder already exists
    if (existsSync(quickbackPath)) {
        console.error(pc.red("Error: quickback folder already exists in this directory"));
        process.exit(1);
    }
    console.log(pc.cyan("Creating quickback project structure..."));
    try {
        // Create folder structure
        mkdirSync(quickbackPath, { recursive: true });
        mkdirSync(join(quickbackPath, "definitions"), { recursive: true });
        mkdirSync(join(quickbackPath, "definitions", "auth"), { recursive: true });
        mkdirSync(join(quickbackPath, "definitions", "features"), { recursive: true });
        mkdirSync(join(quickbackPath, "definitions", "features", "todos"), { recursive: true });
        mkdirSync(join(quickbackPath, "output"), { recursive: true });
        // Create quickback.config.ts with new provider-based format
        //
        // The block between [quickback:options-start] / [quickback:options-end]
        // is owned by Quickback and **regenerated on every `quickback
        // compile`** — the CLI splices in whatever the server returns.
        // Keeping it server-driven means new options appear automatically
        // when you upgrade Quickback (no CLI bump needed) and any options
        // you've already set get omitted from the block to avoid
        // duplication. To enable an option, copy its line *above* the
        // start sentinel; Quickback will preserve it and drop it from the
        // managed block on the next compile.
        const configContent = `/**
 * Quickback Configuration
 *
 * This file defines your backend configuration using the provider system.
 * Use presets for quick setup, or define individual providers for customization.
 *
 * The block between [quickback:options-start] and [quickback:options-end]
 * is regenerated on every \`quickback compile\` to reflect the current set
 * of options Quickback supports — auth flavors, file uploads, agent
 * surfaces, ETag, OpenAPI publishing, custom bindings, and so on. Copy
 * any line you want to enable *above* the start sentinel; Quickback
 * preserves anything outside the marker block and drops it from the
 * managed block on the next compile.
 */
import { defineConfig } from "@quickback/compiler";
import { cloudflare } from "@quickback/compiler/presets";

export default defineConfig({
    // Project settings
    name: "my-quickback-app",
    template: "hono", // "hono" | "nextjs"

    // Use a preset for quick setup (includes runtime, database, storage, auth)
    providers: cloudflare({
        // Optional customization:
        // databaseBinding: "DATABASE",
        // kvBinding: "KV",
    }),

    // Build settings
    build: {
        outputDir: "./output",
    },

    // [quickback:options-start]
    // Run \`quickback compile\` to populate this block with every available option.
    // [quickback:options-end]
});

/**
 * Alternative: For local development with Bun and SQLite, use:
 *
 * import { bun } from "@quickback/compiler/presets";
 *
 * providers: bun({
 *     databasePath: "./data/app.db",
 * }),
 */
`;
        writeFileSync(join(quickbackPath, "quickback.config.ts"), configContent);
        // Create auth definition
        const authConfigContent = `/**
 * Better Auth Configuration
 * 
 * This file defines your authentication configuration for Better Auth.
 * Modify this to customize authentication behavior in your application.
 */

export const authConfig = {
    // Core settings
    autoDetectIpAddress: true,
    geolocationTracking: true,
    
    // Authentication methods
    emailAndPassword: {
        enabled: true,
        requireEmailVerification: false
    },
    
    // Plugins - Add or remove based on your needs
    // Available plugins: "anonymous", "openAPI", "twoFactor", "passkey", "magicLink"
    plugins: ["anonymous"],
    
    // Rate limiting configuration
    rateLimit: {
        enabled: true,
        window: 60, // seconds (minimum for KV is 60s)
        max: 100, // requests per window
        customRules: {
            // Add custom rate limit rules for specific endpoints
            "/sign-in/email": {
                window: 60,
                max: 10
            },
            "/sign-in/social": {
                window: 60,
                max: 10
            }
        }
    },
    
    // Social providers - Enable and configure as needed
    socialProviders: {
        google: {
            enabled: false,
            // clientId and clientSecret will be read from environment variables
        },
        github: {
            enabled: false,
        },
        discord: {
            enabled: false,
        }
    },
    
    // Session configuration
    session: {
        expiresInDays: 30,
        updateAgeInDays: 1
    },
    
    // Database configuration
    database: {
        // Additional database-specific options
        usePlural: true, // Use plural table names (users, sessions, etc.)
        debugLogs: true  // Enable debug logging for database operations
    }
};
`;
        writeFileSync(join(quickbackPath, "definitions", "auth", "better-auth.ts"), authConfigContent);
        // Create example todos feature
        const todosSchemaContent = `/**
 * Todos Feature Schema
 * 
 * Example feature definition showing how to create database schemas
 * and API endpoints for your application features.
 */

import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
import { sql } from "drizzle-orm";

export const todos = sqliteTable("todos", {
    id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
    userId: text("user_id").notNull(),
    title: text("title").notNull(),
    description: text("description"),
    completed: integer("completed", { mode: "boolean" }).default(false).notNull(),
    createdAt: integer("created_at", { mode: "timestamp" }).$defaultFn(() => new Date()),
    updatedAt: integer("updated_at", { mode: "timestamp" }).$defaultFn(() => new Date()),
});

export type Todo = typeof todos.$inferSelect;
export type NewTodo = typeof todos.$inferInsert;
`;
        writeFileSync(join(quickbackPath, "definitions", "features", "todos", "schema.ts"), todosSchemaContent);
        // Create todos API routes
        const todosRoutesContent = `/**
 * Todos API Routes
 * 
 * Example API implementation for the todos feature.
 * Shows how to create authenticated CRUD endpoints.
 */

import { Hono } from "hono";
import { eq, and } from "drizzle-orm";
import type { Todo, NewTodo } from "./schema";

export function createTodosRoutes(auth: any, db: any, todos: any) {
    const app = new Hono();

    // Get all todos for the authenticated user
    app.get("/", async (c) => {
        const session = await auth.api.getSession({
            headers: c.req.raw.headers,
        });

        if (!session) {
            return c.json({ error: "Unauthorized" }, 401);
        }

        const userTodos = await db
            .select()
            .from(todos)
            .where(eq(todos.userId, session.user.id));

        return c.json(userTodos);
    });

    // Create a new todo
    app.post("/", async (c) => {
        const session = await auth.api.getSession({
            headers: c.req.raw.headers,
        });

        if (!session) {
            return c.json({ error: "Unauthorized" }, 401);
        }

        const body = await c.req.json<{ title: string; description?: string }>();
        
        if (!body.title) {
            return c.json({ error: "Title is required" }, 400);
        }

        const newTodo: NewTodo = {
            userId: session.user.id,
            title: body.title,
            description: body.description,
        };

        const [todo] = await db.insert(todos).values(newTodo).returning();
        return c.json(todo, 201);
    });

    // Update a todo
    app.patch("/:id", async (c) => {
        const session = await auth.api.getSession({
            headers: c.req.raw.headers,
        });

        if (!session) {
            return c.json({ error: "Unauthorized" }, 401);
        }

        const id = c.req.param("id");
        const body = await c.req.json<{ title?: string; description?: string; completed?: boolean }>();

        const [updatedTodo] = await db
            .update(todos)
            .set({
                ...body,
                updatedAt: new Date(),
            })
            .where(and(eq(todos.id, id), eq(todos.userId, session.user.id)))
            .returning();

        if (!updatedTodo) {
            return c.json({ error: "Todo not found" }, 404);
        }

        return c.json(updatedTodo);
    });

    // Delete a todo
    app.delete("/:id", async (c) => {
        const session = await auth.api.getSession({
            headers: c.req.raw.headers,
        });

        if (!session) {
            return c.json({ error: "Unauthorized" }, 401);
        }

        const id = c.req.param("id");

        const [deletedTodo] = await db
            .delete(todos)
            .where(and(eq(todos.id, id), eq(todos.userId, session.user.id)))
            .returning();

        if (!deletedTodo) {
            return c.json({ error: "Todo not found" }, 404);
        }

        return c.json({ message: "Todo deleted successfully" });
    });

    return app;
}
`;
        writeFileSync(join(quickbackPath, "definitions", "features", "todos", "routes.ts"), todosRoutesContent);
        // Create todos README
        const todosReadmeContent = `# Todos Feature

This is an example feature showing how to structure your application features in Quickback.

## Structure

- **schema.ts** - Defines the database schema using Drizzle ORM
- **routes.ts** - Implements the API endpoints for CRUD operations

## Usage

This feature will be automatically integrated into your application when you run the Quickback compiler. The routes will be mounted at \`/api/todos\`.

## Endpoints

- \`GET /api/todos\` - Get all todos for the authenticated user
- \`POST /api/todos\` - Create a new todo
- \`PATCH /api/todos/:id\` - Update a todo
- \`DELETE /api/todos/:id\` - Delete a todo

All endpoints require authentication via Better Auth sessions.
`;
        writeFileSync(join(quickbackPath, "definitions", "features", "todos", "README.md"), todosReadmeContent);
        // Create .gitignore
        const gitignoreContent = `# Output directory
output/

# Dependencies
node_modules/

# Environment files
.env
.env.local
.env.*.local

# IDE
.vscode/
.idea/

# OS
.DS_Store
Thumbs.db

# Logs
*.log

# Build artifacts
dist/
build/
.next/
`;
        writeFileSync(join(quickbackPath, ".gitignore"), gitignoreContent);
        // Create README
        const readmeContent = `# Quickback Project

This is a Quickback project structure for building Cloudflare Workers applications with authentication.

## Structure

- **quickback.config.ts** - Main configuration file for your project
- **definitions/** - Contains all your feature and configuration definitions
  - **auth/** - Authentication configuration (Better Auth)
  - **features/** - Your application features (APIs, schemas, etc.)
- **output/** - Generated code output (gitignored)

## Getting Started

1. Customize \`quickback.config.ts\` with your project settings
2. Modify \`definitions/auth/better-auth.ts\` for authentication configuration
3. Add your own features in \`definitions/features/\`
4. Run the Quickback compiler to generate your application:

\`\`\`bash
npx @quickback/compiler generate
\`\`\`

## Adding Features

Create a new directory under \`definitions/features/\` with:
- \`schema.ts\` - Database schema definitions
- \`routes.ts\` - API route implementations
- Any other files needed for your feature

## Environment Variables

Configure the following in your \`.env\` file:
- \`CLOUDFLARE_ACCOUNT_ID\` - Your Cloudflare account ID
- Social provider credentials (if using social auth)
- Database connection strings (for Hyperdrive)

## Learn More

- [Quickback Documentation](https://github.com/quickback/quickback-compiler)
- [Better Auth Documentation](https://www.better-auth.com)
- [Cloudflare Workers Documentation](https://developers.cloudflare.com/workers)
`;
        writeFileSync(join(quickbackPath, "README.md"), readmeContent);
        console.log(pc.green("\n✅ Quickback project structure created successfully!"));
        console.log(pc.cyan("\nNext steps:"));
        console.log(pc.white(`  1. cd ${quickbackPath}`));
        console.log(pc.white("  2. Customize quickback.config.ts"));
        console.log(pc.white("  3. Modify auth configuration in definitions/auth/"));
        console.log(pc.white("  4. Add your features in definitions/features/"));
        console.log(pc.white("  5. Run: npx @quickback/compiler generate"));
        console.log(pc.cyan("\nFor more information, see the README.md file in the quickback folder."));
    }
    catch (error) {
        console.error(pc.red("Error creating quickback structure:"), error);
        process.exit(1);
    }
}
//# sourceMappingURL=init.js.map