/**
 * Inline templates for product repo scaffolding.
 * Each template uses {{VARIABLE}} and {{#IF FEATURE}}...{{/IF FEATURE}} syntax.
 */

// ── product.json ─────────────────────────────────────────────────────────────

export const PRODUCT_JSON = `{
  "productId": "{{PRODUCT_ID}}",
  "displayName": "{{DISPLAY_NAME}}",
  "tagline": "{{TAGLINE}}",
  "domain": "{{DOMAIN}}",
  "backendPort": {{BACKEND_PORT}},
  "primarySurface": "{{PRIMARY_SURFACE}}",
  "bundleIds": {
    "web": "{{DOMAIN}}"{{#IF HAS_IOS}},
    "ios": "com.bytelyst.{{PRODUCT_ID}}"{{/IF HAS_IOS}}{{#IF HAS_ANDROID}},
    "android": "com.{{PRODUCT_ID}}.app"{{/IF HAS_ANDROID}}
  },
  "appStore": {
    "category": "Productivity",
    "privacyUrl": "https://{{DOMAIN}}/privacy",
    "termsUrl": "https://{{DOMAIN}}/terms",
    "supportUrl": "https://{{DOMAIN}}/support"
  },
  "version": "0.1.0"
}
`;

// ── .gitignore ───────────────────────────────────────────────────────────────

export const GITIGNORE = `node_modules/
dist/
.next/
.env
.env.local
*.log
.DS_Store
coverage/
`;

// ── .env.example ─────────────────────────────────────────────────────────────

export const ENV_EXAMPLE = `# {{DISPLAY_NAME}} environment variables
NODE_ENV=development
{{#IF HAS_BACKEND}}
# Backend
PORT={{BACKEND_PORT}}
HOST=0.0.0.0
JWT_SECRET=dev-secret-change-me
DB_PROVIDER=memory
COSMOS_ENDPOINT=
COSMOS_KEY=
COSMOS_DATABASE=bytelyst
PLATFORM_SERVICE_URL=http://localhost:4003
{{/IF HAS_BACKEND}}
{{#IF HAS_WEB}}
# Web
NEXT_PUBLIC_BACKEND_URL=http://localhost:{{BACKEND_PORT}}
{{/IF HAS_WEB}}
`;

// ── README.md ────────────────────────────────────────────────────────────────

export const README = `# {{DISPLAY_NAME}}

> {{TAGLINE}}

## Quick Start

\`\`\`bash
{{#IF HAS_BACKEND}}# Backend
cd backend && npm install && npm run dev
{{/IF HAS_BACKEND}}{{#IF HAS_WEB}}# Web
cd web && npm install && npm run dev
{{/IF HAS_WEB}}{{#IF HAS_MOBILE}}# Mobile
cd mobile && npm install && npm start
{{/IF HAS_MOBILE}}\`\`\`

## Architecture

| Layer | Technology |
|-------|-----------|
{{#IF HAS_BACKEND}}| Backend | Fastify 5 + TypeScript ESM (port {{BACKEND_PORT}}) |
{{/IF HAS_BACKEND}}{{#IF HAS_WEB}}| Web | Next.js 16 (App Router) + React 19 |
{{/IF HAS_WEB}}{{#IF HAS_MOBILE}}| Mobile | React Native (Expo) |
{{/IF HAS_MOBILE}}| Platform | platform-service (port 4003) |
| Database | Azure Cosmos DB (\`productId: "{{PRODUCT_ID}}"\`) |

## Product Identity

- **Product ID:** \`{{PRODUCT_ID}}\`
- **Domain:** {{DOMAIN}}
- **Backend Port:** {{BACKEND_PORT}}

See [AGENTS.md](AGENTS.md) for AI agent instructions.
`;

// ── Backend templates ────────────────────────────────────────────────────────

export const BACKEND_PACKAGE_JSON = `{
  "name": "@{{PRODUCT_ID}}/backend",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "tsx watch src/server.ts",
    "build": "tsc",
    "start": "node dist/server.js",
    "test": "vitest run",
    "typecheck": "tsc --noEmit"
  },
  "dependencies": {
    "@bytelyst/config": "file:../../learning_ai_common_plat/packages/config",
    "@bytelyst/cosmos": "file:../../learning_ai_common_plat/packages/cosmos",
    "@bytelyst/datastore": "file:../../learning_ai_common_plat/packages/datastore",
    "@bytelyst/errors": "file:../../learning_ai_common_plat/packages/errors",
    "@bytelyst/fastify-core": "file:../../learning_ai_common_plat/packages/fastify-core",
    "fastify": "^5.3.3",
    "jose": "^6.0.11",
    "zod": "^3.24.4"
  },
  "devDependencies": {
    "tsx": "^4.19.2",
    "typescript": "^5.7.3",
    "vitest": "^3.0.5"
  }
}
`;

export const BACKEND_TSCONFIG = `{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "outDir": "dist",
    "rootDir": "src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "resolveJsonModule": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true
  },
  "include": ["src"],
  "exclude": ["dist", "src/**/*.test.ts"]
}
`;

export const BACKEND_CONFIG = `import { z } from 'zod';
import { PRODUCT_ID } from './product-config.js';

const envSchema = z.object({
  PORT: z.coerce.number().default({{BACKEND_PORT}}),
  HOST: z.string().default('0.0.0.0'),
  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
  CORS_ORIGIN: z.string().optional(),
  SERVICE_NAME: z.string().default('{{PRODUCT_ID}}-backend'),
  COSMOS_ENDPOINT: z.string().optional(),
  COSMOS_KEY: z.string().optional(),
  COSMOS_DATABASE: z.string().default('bytelyst'),
  JWT_SECRET: z.string().min(1, 'JWT_SECRET is required'),
  DB_PROVIDER: z.enum(['cosmos', 'memory']).default('cosmos'),
  PRODUCT_ID: z.string().default(PRODUCT_ID),
  PLATFORM_SERVICE_URL: z.string().default('http://localhost:4003'),
});

export const config = envSchema.parse(process.env);
`;

export const BACKEND_PRODUCT_CONFIG = `import { readFileSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const raw = readFileSync(join(__dirname, '../../../shared/product.json'), 'utf-8');
const manifest = JSON.parse(raw);
export const PRODUCT_ID: string = manifest.productId;
`;

export const BACKEND_AUTH = `import { jwtVerify, createRemoteJWKSet } from 'jose';
import type { FastifyRequest } from 'fastify';
import { config } from './config.js';

const secret = new TextEncoder().encode(config.JWT_SECRET);

export interface JwtPayload {
  sub: string;
  email?: string;
  role?: string;
}

export async function verifyToken(token: string): Promise<JwtPayload | null> {
  try {
    const { payload } = await jwtVerify(token, secret);
    return payload as unknown as JwtPayload;
  } catch {
    return null;
  }
}

export function extractToken(req: FastifyRequest): string | null {
  const auth = req.headers.authorization;
  if (!auth?.startsWith('Bearer ')) return null;
  return auth.slice(7);
}
`;

export const BACKEND_REQUEST_CONTEXT = `import type { FastifyRequest } from 'fastify';
import { verifyToken, extractToken, type JwtPayload } from './auth.js';
import { config } from './config.js';

export async function getUserPayload(req: FastifyRequest): Promise<JwtPayload | null> {
  const token = extractToken(req);
  if (!token) return null;
  return verifyToken(token);
}

export function getUserId(req: FastifyRequest & { user?: JwtPayload }): string {
  if (!req.user?.sub) throw new Error('Unauthenticated');
  return req.user.sub;
}

export function getRequestProductId(_req: FastifyRequest): string {
  return config.PRODUCT_ID;
}
`;

export const BACKEND_ERRORS = `export { BadRequestError, NotFoundError, ConflictError, ForbiddenError } from '@bytelyst/errors';
`;

export const BACKEND_DATASTORE = `import { config } from './config.js';

const collections = new Map<string, Map<string, unknown>>();

export function getCollection<T = unknown>(name: string): Map<string, T> {
  if (!collections.has(name)) {
    collections.set(name, new Map());
  }
  return collections.get(name) as Map<string, T>;
}

export const PRODUCT_ID = config.PRODUCT_ID;
export const DB_PROVIDER = config.DB_PROVIDER;
`;

export const BACKEND_SERVER = `import Fastify from 'fastify';
import { config } from './lib/config.js';

const app = Fastify({
  logger: {
    level: config.NODE_ENV === 'test' ? 'silent' : 'info',
  },
});

// CORS
if (config.CORS_ORIGIN) {
  app.addHook('onRequest', async (request, reply) => {
    reply.header('Access-Control-Allow-Origin', config.CORS_ORIGIN);
    reply.header('Access-Control-Allow-Methods', 'GET,POST,PATCH,PUT,DELETE,OPTIONS');
    reply.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
    if (request.method === 'OPTIONS') {
      reply.status(204).send();
    }
  });
}

// Health check
app.get('/health', async () => ({
  status: 'ok',
  service: config.SERVICE_NAME,
  productId: config.PRODUCT_ID,
}));

// TODO: Register your route modules here
// import { routes as exampleRoutes } from './modules/example/routes.js';
// app.register(exampleRoutes, { prefix: '/api' });

async function start() {
  try {
    await app.listen({ port: config.PORT, host: config.HOST });
    app.log.info(\`{{DISPLAY_NAME}} backend listening on port \${config.PORT}\`);
  } catch (err) {
    app.log.error(err);
    process.exit(1);
  }
}

start();

export { app };
`;

// ── Web templates ────────────────────────────────────────────────────────────

export const WEB_PACKAGE_JSON = `{
  "name": "@{{PRODUCT_ID}}/web",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build --webpack",
    "start": "next start",
    "typecheck": "tsc --noEmit"
  },
  "dependencies": {
    "next": "^16.0.0",
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  },
  "devDependencies": {
    "@types/node": "^22.16.0",
    "@types/react": "^19.2.0",
    "@types/react-dom": "^19.2.0",
    "typescript": "^5.7.3"
  }
}
`;

export const WEB_TSCONFIG = `{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "plugins": [{ "name": "next" }],
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}
`;

export const WEB_NEXT_CONFIG = `import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  reactStrictMode: true,
};

export default nextConfig;
`;

export const WEB_LAYOUT = `import type { Metadata } from 'next';

export const metadata: Metadata = {
  title: '{{DISPLAY_NAME}}',
  description: '{{TAGLINE}}',
};

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}
`;

export const WEB_PAGE = `export default function Home() {
  return (
    <main style={{ padding: '2rem', maxWidth: '800px', margin: '0 auto', fontFamily: 'system-ui' }}>
      <h1>{{DISPLAY_NAME}}</h1>
      <p>{{TAGLINE}}</p>
      <p>Edit <code>src/app/page.tsx</code> to get started.</p>
    </main>
  );
}
`;

export const WEB_PRODUCT_CONFIG = `const manifest = {
  productId: '{{PRODUCT_ID}}',
  displayName: '{{DISPLAY_NAME}}',
  domain: '{{DOMAIN}}',
  backendPort: {{BACKEND_PORT}},
};

export const PRODUCT_ID = manifest.productId;

export function getBackendURL(): string {
  return process.env.NEXT_PUBLIC_BACKEND_URL ?? 'http://localhost:{{BACKEND_PORT}}';
}

export default manifest;
`;

// ── Mobile (Expo) templates ──────────────────────────────────────────────────

export const MOBILE_PACKAGE_JSON = `{
  "name": "@{{PRODUCT_ID}}/mobile",
  "version": "0.1.0",
  "private": true,
  "main": "expo-router/entry",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "typecheck": "tsc --noEmit"
  },
  "dependencies": {
    "expo": "~55.0.0",
    "expo-router": "~5.0.0",
    "react": "^19.0.0",
    "react-native": "^0.79.0"
  },
  "devDependencies": {
    "@types/react": "^19.2.0",
    "typescript": "^5.7.3"
  }
}
`;

export const MOBILE_APP_JSON = `{
  "expo": {
    "name": "{{DISPLAY_NAME}}",
    "slug": "{{PRODUCT_ID}}",
    "version": "1.0.0",
    "scheme": "{{PRODUCT_ID}}",
    "platforms": ["ios", "android"],
    "ios": {
      "bundleIdentifier": "com.bytelyst.{{PRODUCT_ID}}"
    },
    "android": {
      "package": "com.{{PRODUCT_ID}}.app"
    }
  }
}
`;

export const MOBILE_INDEX = `import { View, Text, StyleSheet } from 'react-native';

export default function Home() {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>{{DISPLAY_NAME}}</Text>
      <Text style={styles.subtitle}>{{TAGLINE}}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 },
  title: { fontSize: 28, fontWeight: '700', marginBottom: 8 },
  subtitle: { fontSize: 16, color: '#666' },
});
`;
