<?php

namespace Config;

use CodeIgniter\Config\BaseConfig;

/**
 * Multi-tenancy configuration (database-per-hotel).
 *
 * This does NOT list individual tenant databases — those are looked up at
 * request time from the `tenants` table in the control database (see
 * App\Models\Control\TenantRecordModel). It only holds the connection
 * template (host/credentials/driver) shared by every tenant database on
 * this server, plus the local-dev fallback slug used when no subdomain
 * is present.
 */
class Tenancy extends BaseConfig
{
    /**
     * Prefix every physical tenant database name is expected to carry,
     * e.g. slug "demo" -> database "tenant_demo". Enforced by the
     * provisioning command so tenant DB names never collide with the
     * control DB or anything else on the MySQL server.
     *
     * Overridable via tenant.db.namePrefix — needed on shared cPanel
     * hosting, where every database name is forced to carry the cPanel
     * account's own username as a prefix (e.g. "myuser_tenant_"), which
     * this app has no way to know at write-time. See $autoCreateDatabase
     * below for why cPanel needs this changed too.
     */
    public string $dbNamePrefix = 'tenant_';

    /**
     * Whether TenantProvisioner is allowed to run CREATE DATABASE itself
     * when onboarding a new hotel. True everywhere this app controls its
     * own MySQL server (local dev, a VPS/dedicated box with WHM+root) —
     * the app's DB user there genuinely has CREATE DATABASE privilege.
     *
     * False on shared cPanel hosting: cPanel scopes a database user to
     * specific, pre-created databases and never grants CREATE DATABASE
     * to it. There, an admin creates the (empty) database by hand via
     * cPanel's "MySQL Databases" tool first — using the exact name
     * dbNamePrefix + slug resolves to — grants the app's db user access
     * to it there, and only then provisions the hotel from the app;
     * TenantProvisioner just verifies that database already exists and
     * is empty before migrating into it, rather than trying to create it.
     * Overridable via tenant.db.autoCreate.
     */
    public bool $autoCreateDatabase = true;

    /**
     * Shared connection template used to build a live connection to a
     * specific tenant database once its slug has been resolved. Only
     * `database` differs per tenant (see TenantContext::buildConnection()).
     *
     * @var array<string, mixed>
     */
    public array $dbTemplate = [
        'DSN'      => '',
        'hostname' => '127.0.0.1',
        'username' => '',
        'password' => '',
        'DBDriver' => 'MySQLi',
        'DBPrefix' => '',
        'pConnect' => false,
        'DBDebug'  => true,
        'charset'  => 'utf8mb4',
        'DBCollat' => 'utf8mb4_unicode_ci',
        'port'     => 3306,
    ];

    /**
     * Local-dev fallback tenant slug, used when the request host has no
     * usable subdomain (e.g. plain http://localhost:8080) and no tenant
     * has been chosen via the dev tenant switcher yet.
     */
    public ?string $defaultSlug = null;

    /**
     * Host labels that never count as a tenant subdomain, so
     * "localhost:8080" or "127.0.0.1:8080" don't get parsed as a slug.
     *
     * @var list<string>
     */
    public array $nonTenantHosts = ['localhost', '127.0.0.1'];

    public function __construct()
    {
        parent::__construct();

        $this->dbNamePrefix      = (string) env('tenant.db.namePrefix', $this->dbNamePrefix);
        $this->autoCreateDatabase = filter_var(env('tenant.db.autoCreate', $this->autoCreateDatabase), FILTER_VALIDATE_BOOLEAN);

        $this->dbTemplate['hostname'] = env('tenant.db.hostname', $this->dbTemplate['hostname']);
        $this->dbTemplate['username'] = (string) env('tenant.db.username', $this->dbTemplate['username']);
        $this->dbTemplate['password'] = (string) env('tenant.db.password', $this->dbTemplate['password']);
        $this->dbTemplate['DBDriver'] = env('tenant.db.DBDriver', $this->dbTemplate['DBDriver']);
        $this->dbTemplate['charset']  = env('tenant.db.charset', $this->dbTemplate['charset']);
        $this->dbTemplate['DBCollat'] = env('tenant.db.DBCollat', $this->dbTemplate['DBCollat']);
        $this->dbTemplate['port']     = (int) env('tenant.db.port', $this->dbTemplate['port']);

        $this->defaultSlug = env('tenant.defaultSlug', $this->defaultSlug);
    }
}
