package cmd

import "fmt"

func gitignoreFor(stackType string) string {
	base := ".env\n.env.*\n!.env.example\n"
	switch stackType {
	case "node":
		return base + "node_modules/\ndist/\n.next/\n*.log\n"
	case "python":
		return base + "__pycache__/\n*.pyc\n.venv/\nvenv/\n*.egg-info/\ndist/\nbuild/\n"
	case "go":
		return base + "*.exe\n*.test\n*.out\n/vendor/\n"
	case "static":
		return base + "dist/\n.cache/\n"
	}
	return base
}

func dockerComposeTemplate(name, stackType string, port int) string {
	projectsDir := "~/projects"
	var svc string
	switch stackType {
	case "node":
		svc = fmt.Sprintf(
			"  app:\n    image: ${IMAGE:-ghcr.io/sketchferret/%s:latest}\n"+
				"    build: %s/%s\n"+
				"    restart: unless-stopped\n    ports:\n      - \"%d:3000\"\n    env_file: .env\n",
			name, projectsDir, name, port)
	case "python":
		svc = fmt.Sprintf(
			"  app:\n    image: ${IMAGE:-ghcr.io/sketchferret/%s:latest}\n"+
				"    build: %s/%s\n"+
				"    restart: unless-stopped\n    ports:\n      - \"%d:8000\"\n    env_file: .env\n",
			name, projectsDir, name, port)
	case "go":
		svc = fmt.Sprintf(
			"  app:\n    image: ${IMAGE:-ghcr.io/sketchferret/%s:latest}\n"+
				"    build: %s/%s\n"+
				"    restart: unless-stopped\n    ports:\n      - \"%d:8080\"\n    env_file: .env\n",
			name, projectsDir, name, port)
	case "static":
		svc = fmt.Sprintf(
			"  web:\n    image: nginx:alpine\n    restart: unless-stopped\n"+
				"    ports:\n      - \"%d:80\"\n    volumes:\n      - ./dist:/usr/share/nginx/html:ro\n",
			port)
	}
	return "services:\n" + svc
}

func dotEnvExample(name, stackType string, port int) string {
	_ = port // host port is set by compose; container uses its own internal port
	header := fmt.Sprintf("# %s environment\n# Copy to .env and fill in values\n\n", name)
	switch stackType {
	case "node":
		return header + "PORT=3000\n# DATABASE_URL=\n# SECRET_KEY=\n"
	case "python":
		return header + "PORT=8000\n# DATABASE_URL=\n# SECRET_KEY=\n"
	case "go":
		return header + "PORT=8080\n# DATABASE_URL=\n"
	}
	return header
}

func caddySnippet(subdomain, proxyHost string, port int) string {
	return fmt.Sprintf("%s {\n\treverse_proxy %s:%d\n}\n", subdomain, proxyHost, port)
}

// --- local starter files ---

func nodePackageJSON(name string) string {
	return fmt.Sprintf(`{
  "name": "%s",
  "version": "0.1.0",
  "scripts": {
    "dev": "ts-node src/index.ts",
    "build": "tsc",
    "start": "node dist/index.js"
  },
  "dependencies": {},
  "devDependencies": {
    "typescript": "^5.0.0",
    "ts-node": "^10.0.0",
    "@types/node": "^20.0.0"
  }
}
`, name)
}

func tsconfigJSON() string {
	return `{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "outDir": "dist",
    "rootDir": "src",
    "strict": true,
    "esModuleInterop": true
  }
}
`
}

func nodeIndexTS() string {
	// Template literal backtick handled via concatenation
	return "import http from 'http';\n\n" +
		"const port = process.env.PORT ? parseInt(process.env.PORT) : 3000;\n\n" +
		"const server = http.createServer((_req, res) => {\n" +
		"  res.writeHead(200, { 'Content-Type': 'text/plain' });\n" +
		"  res.end('Hello World\\n');\n" +
		"});\n\n" +
		"server.listen(port, () => {\n" +
		"  console.log(`Server running on port ${port}`);\n" +
		"});\n"
}

func nodeDockerfile() string {
	return `FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]
`
}

func pythonApp() string {
	return `from flask import Flask

app = Flask(__name__)


@app.route("/")
def index():
    return "Hello World"


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)
`
}

func pythonDockerfile() string {
	return `FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "app.py"]
`
}

func goMod(name string) string {
	return fmt.Sprintf("module %s\n\ngo 1.22\n", name)
}

func goMain() string {
	return `package main

import (
	"fmt"
	"net/http"
	"os"
)

func main() {
	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "Hello World")
	})
	fmt.Println("Listening on :" + port)
	if err := http.ListenAndServe(":"+port, nil); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}
`
}

func goDockerfile() string {
	return `FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o app .

FROM scratch
COPY --from=builder /app/app /app
EXPOSE 8080
CMD ["/app"]
`
}

func staticHTML(name string) string {
	return fmt.Sprintf(`<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>%s</title>
</head>
<body>
  <h1>%s</h1>
</body>
</html>
`, name, name)
}

func staticDockerfile() string {
	return `FROM nginx:alpine
COPY . /usr/share/nginx/html
EXPOSE 80
`
}
