param(
  [string]$ClusterName = "dsys",
  [string]$KindConfigPath = ".\kubernetes\kind-config.yaml",
  [string]$ApiImage = "search-first-dis-storage:latest",
  [switch]$SkipBuildApiImage,
  [switch]$RecreateCluster,
  [int]$WaitTimeoutSeconds = 600
)

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
if (Get-Variable PSNativeCommandUseErrorActionPreference -ErrorAction SilentlyContinue) {
  $PSNativeCommandUseErrorActionPreference = $false
}

function Require-Command {
  param([string]$Name)
  if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) {
    throw "Required command '$Name' not found in PATH."
  }
}

function Test-KindClusterExists {
  param([string]$Name)
  $clustersRaw = cmd /c "kind get clusters 2>nul"
  if ($LASTEXITCODE -ne 0 -or -not $clustersRaw) {
    return $false
  }

  $clusters = ($clustersRaw | Out-String).Trim() -split "`r?`n"
  return ($clusters -contains $Name)
}

Require-Command "docker"
Require-Command "kubectl"
Require-Command "kind"

$repoRoot = Split-Path -Parent $PSScriptRoot
$resolvedKindConfigPath = Join-Path $repoRoot $KindConfigPath

if (-not (Test-Path $resolvedKindConfigPath)) {
  throw "Kind config not found: $resolvedKindConfigPath"
}

if (Test-KindClusterExists -Name $ClusterName) {
  if ($RecreateCluster) {
    Write-Host "[cluster] Deleting existing kind cluster '$ClusterName'..."
    kind delete cluster --name $ClusterName
  } else {
    Write-Host "[cluster] Kind cluster '$ClusterName' already exists, reusing it."
  }
}

if (-not (Test-KindClusterExists -Name $ClusterName)) {
  Write-Host "[cluster] Creating kind cluster '$ClusterName'..."
  kind create cluster --name $ClusterName --config $resolvedKindConfigPath
}

if (-not $SkipBuildApiImage) {
  Write-Host "[image] Building API image '$ApiImage'..."
  docker build -t $ApiImage $repoRoot
}

Write-Host "[image] Loading API image '$ApiImage' into kind cluster '$ClusterName'..."
kind load docker-image $ApiImage --name $ClusterName

Write-Host "[k8s] Creating namespaces..."
kubectl create namespace search --dry-run=client -o yaml | kubectl apply -f -
kubectl create namespace storage --dry-run=client -o yaml | kubectl apply -f -

Write-Host "[k8s] Applying manifests..."
Write-Host "[k8s] Installing/Updating Metrics Server..."
kubectl apply -f "https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml"
$metricsServerPatchPath = Join-Path $repoRoot "kubernetes\metrics-server-kind-patch.json"
kubectl -n kube-system patch deployment metrics-server --type strategic --patch-file $metricsServerPatchPath

kubectl apply -f (Join-Path $repoRoot "kubernetes\elasticsearch.yaml")
kubectl apply -f (Join-Path $repoRoot "kubernetes\elasticsearch-service.yaml")
kubectl apply -f (Join-Path $repoRoot "kubernetes\minio.yaml")
kubectl apply -f (Join-Path $repoRoot "kubernetes\node.yaml")
kubectl apply -f (Join-Path $repoRoot "kubernetes\api-hpa.yaml")
kubectl apply -f (Join-Path $repoRoot "kubernetes\api-loadbalancer-service.yaml")

Write-Host "[k8s] Setting API image to '$ApiImage'..."
kubectl set image deployment/api api=$ApiImage


Write-Host "[k8s] Ensuring internal services exist..."
@"
apiVersion: v1
kind: Service
metadata:
  name: minio
  namespace: storage
spec:
  clusterIP: None
  selector:
    app: minio
  ports:
    - name: api
      port: 9000
      targetPort: 9000
"@ | kubectl apply -f -

@"
apiVersion: v1
kind: Service
metadata:
  name: api
spec:
  selector:
    app: api
  ports:
    - name: http
      port: 3000
      targetPort: 3000
"@ | kubectl apply -f -

$timeout = "$($WaitTimeoutSeconds)s"

Write-Host "[k8s] Waiting for Elasticsearch StatefulSet..."
kubectl -n search rollout status statefulset/elasticsearch --timeout=$timeout

Write-Host "[k8s] Waiting for MinIO StatefulSet..."
kubectl -n storage rollout status statefulset/minio --timeout=$timeout

Write-Host "[k8s] Waiting for API Deployment..."
kubectl rollout status deployment/api --timeout=$timeout

Write-Host "[k8s] Waiting for Metrics Server Deployment..."
$metricsRolloutOk = $true
try {
  kubectl -n kube-system rollout status deployment/metrics-server --timeout=$timeout
} catch {
  $metricsRolloutOk = $false
}

if (-not $metricsRolloutOk) {
  Write-Host "[k8s] Metrics Server failed to become ready within timeout. Diagnostics:"
  kubectl -n kube-system get pods -l k8s-app=metrics-server -o wide

  $metricsPodName = kubectl -n kube-system get pods -l k8s-app=metrics-server -o jsonpath="{.items[0].metadata.name}" 2>$null
  if ($metricsPodName) {
    Write-Host ""
    Write-Host "[k8s] metrics-server pod describe:"
    kubectl -n kube-system describe pod $metricsPodName
    Write-Host ""
    Write-Host "[k8s] metrics-server pod logs:"
    kubectl -n kube-system logs $metricsPodName --all-containers=true --tail=200
  }

  throw "Metrics Server rollout did not complete. See diagnostics above."
}

Write-Host ""
Write-Host "Cluster deployment complete."
Write-Host "Check pods: kubectl get pods -A"
Write-Host "Container CPU/memory: kubectl top pods -A --containers"
Write-Host "Health endpoint: http://localhost:3000/health (alias of /api/health)"
Write-Host "Then open: http://localhost:3000"
Write-Host ""
Write-Host "Note: If this cluster was created before port-mapping changes, recreate it:"
Write-Host "  .\scripts\deploy-cluster.ps1 -RecreateCluster"
