# Kubernetes Namespace
resource "kubernetes_namespace" "app" {
  metadata {
    name = var.app_namespace
    labels = merge(
      local.common_labels,
      {
        name = var.app_namespace
      }
    )
  }
}

# Kubernetes Secret for Database Connection
resource "kubernetes_secret" "db_credentials" {
  metadata {
    name      = "${var.app_name}-db-credentials"
    namespace = kubernetes_namespace.app.metadata[0].name
    labels    = local.common_labels
  }

  data = {
    # Primary connection uses DB_HOST2 variables (for pgsql_second connection)
    DB_CONNECTION2 = "pgsql"
    DB_HOST2       = "postgresql.${kubernetes_namespace.app.metadata[0].name}.svc.cluster.local"
    DB_PORT2       = "5432"
    DB_DATABASE2   = local.postgresql_db_name
    DB_USERNAME2   = var.postgresql_admin_username
    DB_PASSWORD2   = local.postgresql_admin_pass

    # Also set standard DB_ variables for pgsql connection (used by sessions)
    DB_CONNECTION = "pgsql"
    DB_HOST       = "postgresql.${kubernetes_namespace.app.metadata[0].name}.svc.cluster.local"
    DB_PORT       = "5432"
    DB_DATABASE   = local.postgresql_db_name
    DB_USERNAME   = var.postgresql_admin_username
    DB_PASSWORD   = local.postgresql_admin_pass
  }

  type = "Opaque"

  depends_on = [
    kubernetes_service.postgresql
  ]
}

# Kubernetes Secret for Laravel Application
resource "kubernetes_secret" "app_secrets" {
  metadata {
    name      = "${var.app_name}-secrets"
    namespace = kubernetes_namespace.app.metadata[0].name
    labels    = local.common_labels
  }

  data = {
    APP_KEY = var.app_key
  }

  type = "Opaque"
}

# Kubernetes ConfigMap for Laravel Application
resource "kubernetes_config_map" "app_config" {
  metadata {
    name      = "${var.app_name}-config"
    namespace = kubernetes_namespace.app.metadata[0].name
    labels    = local.common_labels
  }

  data = {
    APP_NAME              = var.app_name
    APP_ENV               = var.app_env
    APP_DEBUG             = tostring(var.app_debug)
    APP_URL               = local.app_url
    APP_LOCALE            = "en"
    APP_FALLBACK_LOCALE   = "en"
    APP_FAKER_LOCALE      = "en_US"
    LOG_CHANNEL           = "stack"
    LOG_STACK             = "single"
    LOG_LEVEL             = "info"
    SESSION_DRIVER        = "database"
    SESSION_CONNECTION    = "pgsql"
    SESSION_LIFETIME      = "120"
    SESSION_ENCRYPT       = "false"
    CACHE_STORE           = "database"
    QUEUE_CONNECTION      = "database"
    BROADCAST_CONNECTION  = "log"
    FILESYSTEM_DISK       = "local"
    MAIL_MAILER           = "log"
    VITE_APP_NAME         = var.app_name
  }
}

# Kubernetes Deployment for Laravel Application
resource "kubernetes_deployment" "app" {
  metadata {
    name      = var.app_name
    namespace = kubernetes_namespace.app.metadata[0].name
    labels    = local.common_labels
  }

  spec {
    replicas = var.app_replicas

    selector {
      match_labels = {
        app = var.app_name
      }
    }

    template {
      metadata {
        labels = merge(
          local.common_labels,
          {
            version = "latest"
          }
        )
      }

      spec {
        image_pull_secrets {
          name = "acr-secret"
        }

        container {
          name  = var.app_name
          image = var.docker_image

          port {
            name           = "http"
            container_port = 80
            protocol       = "TCP"
          }

          env_from {
            config_map_ref {
              name = kubernetes_config_map.app_config.metadata[0].name
            }
          }

          env_from {
            secret_ref {
              name = kubernetes_secret.app_secrets.metadata[0].name
            }
          }

          env_from {
            secret_ref {
              name = kubernetes_secret.db_credentials.metadata[0].name
            }
          }

          resources {
            requests = {
              cpu    = var.app_resources_requests_cpu
              memory = var.app_resources_requests_memory
            }
            limits = {
              cpu    = var.app_resources_limits_cpu
              memory = var.app_resources_limits_memory
            }
          }

          liveness_probe {
            exec {
              command = ["sh", "-c", "ps aux | grep -v grep | grep -q nginx && ps aux | grep -v grep | grep -q php-fpm"]
            }
            initial_delay_seconds = 30
            period_seconds        = 10
            timeout_seconds       = 5
            failure_threshold     = 3
          }

          readiness_probe {
            exec {
              command = ["sh", "-c", "ps aux | grep -v grep | grep -q nginx && ps aux | grep -v grep | grep -q php-fpm"]
            }
            initial_delay_seconds = 10
            period_seconds        = 5
            timeout_seconds       = 3
            failure_threshold     = 3
          }
        }

        restart_policy = "Always"
      }
    }

    strategy {
      type = "RollingUpdate"
      rolling_update {
        max_surge       = "1"
        max_unavailable = "0"
      }
    }
  }

  depends_on = [
    kubernetes_secret.db_credentials,
    kubernetes_secret.app_secrets,
    kubernetes_config_map.app_config
  ]
}

# Kubernetes Service for Laravel Application
resource "kubernetes_service" "app" {
  metadata {
    name      = var.app_name
    namespace = kubernetes_namespace.app.metadata[0].name
    labels    = local.common_labels
  }

  spec {
    selector = {
      app = var.app_name
    }

    port {
      name        = "http"
      port        = 80
      target_port = 80
      protocol    = "TCP"
    }

    type = "ClusterIP"
  }

  depends_on = [
    kubernetes_deployment.app
  ]
}

# Horizontal Pod Autoscaler
resource "kubernetes_horizontal_pod_autoscaler_v2" "app" {
  metadata {
    name      = "${var.app_name}-hpa"
    namespace = kubernetes_namespace.app.metadata[0].name
    labels    = local.common_labels
  }

  spec {
    scale_target_ref {
      api_version = "apps/v1"
      kind        = "Deployment"
      name        = kubernetes_deployment.app.metadata[0].name
    }

    min_replicas = var.app_replicas
    max_replicas = var.app_replicas * 3

    metric {
      type = "Resource"
      resource {
        name = "cpu"
        target {
          type                = "Utilization"
          average_utilization = 80
        }
      }
    }

    metric {
      type = "Resource"
      resource {
        name = "memory"
        target {
          type                = "Utilization"
          average_utilization = 80
        }
      }
    }
  }
}
