package k8s

import (
	"fmt"
	"strings"

	"deployment-manager/internal/model"
)

func GenerateDeploymentManifest(repo *model.Repo, imageName string) string {
	appName := GetAppName(repo)
	port := getAppPort(repo.Type)
	
	return fmt.Sprintf(`apiVersion: apps/v1
kind: Deployment
metadata:
  name: %s
  labels:
    app: %s
    repo-id: "%d"
spec:
  replicas: 1
  selector:
    matchLabels:
      app: %s
  template:
    metadata:
      labels:
        app: %s
        repo-id: "%d"
    spec:
      containers:
      - name: %s
        image: %s
        ports:
        - containerPort: %d
        env:
        - name: PORT
          value: "%d"
        resources:
          requests:
            memory: "64Mi"
            cpu: "50m"
          limits:
            memory: "256Mi"
            cpu: "200m"
---
apiVersion: v1
kind: Service
metadata:
  name: %s
  labels:
    app: %s
    repo-id: "%d"
spec:
  selector:
    app: %s
  ports:
  - port: 80
    targetPort: %d
    protocol: TCP
  type: ClusterIP
`, appName, appName, repo.ID, appName, appName, repo.ID, appName, imageName, port, port, appName, appName, repo.ID, appName, port)
}

func GenerateConfigMapManifest(repo *model.Repo) string {
	appName := GetAppName(repo)
	
	return fmt.Sprintf(`apiVersion: v1
kind: ConfigMap
metadata:
  name: %s
  labels:
    app: %s
    repo-id: "%d"
data:
  repo-url: "%s"
  repo-type: "%s"
  user-id: "%s"
`, appName, appName, repo.ID, repo.RepoURL, repo.Type, repo.UserID)
}

func GenerateIngressManifest(repo *model.Repo) string {
	appName := GetAppName(repo)
	host := fmt.Sprintf("repo-%d.example.com", repo.ID)
	
	return fmt.Sprintf(`apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: %s
  labels:
    app: %s
    repo-id: "%d"
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: %s
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: %s
            port:
              number: 80
`, appName, appName, repo.ID, host, appName)
}

func getAppPort(repoType model.RepoType) int {
	switch repoType {
	case model.TypeNodeJS:
		return 3000
	case model.TypePython:
		return 8000
	default:
		return 8080
	}
}

func GenerateFullManifest(repo *model.Repo, imageName string) string {
	var manifest strings.Builder
	
	manifest.WriteString(GenerateDeploymentManifest(repo, imageName))
	manifest.WriteString("\n---\n")
	manifest.WriteString(GenerateConfigMapManifest(repo))
	manifest.WriteString("\n---\n")
	manifest.WriteString(GenerateIngressManifest(repo))
	
	return manifest.String()
}
