/**
 * Residential module gate. Port-scoped on/off switch for the entire
 * Residential surface (sidebar "Residential" section, the
 * /residential/clients + /residential/interests pages, the admin
 * residential-stages page, the global-search residential buckets, and
 * the public residential-inquiry intake endpoint).
 *
 * Defaults to ENABLED so existing ports keep the feature on deploy —
 * residential is in active use, unlike Tenancies / Invoices which are
 * opt-in. When an admin turns it off:
 *  - the sidebar "Residential" section + mobile "Residential" entry
 *    disappear via the port-resolved residentialModuleByPort prop
 *  - the /residential/* and admin/residential-stages routes render a
 *    "module disabled" page instead of the real content, so bookmarks
 *    land somewhere meaningful and direct API hits are rejected at the
 *    layout boundary
 *  - the public /api/public/residential-inquiries endpoint hard-fails
 *    so a disabled port stops accepting residential leads it can't see
 *  - previously-recorded residential clients/interests are preserved
 *    (no destructive cleanup) so re-enabling restores everything
 *
 * Mirrors the Tenancies / Expenses / Invoices module-gate pattern.
 */

import { and, eq, isNull, or } from 'drizzle-orm';

import { db } from '@/lib/db';
import { systemSettings } from '@/lib/db/schema/system';
import { NotFoundError } from '@/lib/errors';

const SETTING_KEY = 'residential_module_enabled';

/**
 * Resolve whether the Residential module is currently active for the
 * given port. Reads from `system_settings.residential_module_enabled`
 * (port-scoped row first, then global row, then registry default = true).
 *
 * Defaulting to enabled mirrors how residential behaved before the
 * toggle existed: deploying this change to a port that has never
 * configured the setting leaves the feature visible.
 */
export async function isResidentialModuleEnabled(portId: string): Promise<boolean> {
  const settingRow = await db
    .select({ value: systemSettings.value })
    .from(systemSettings)
    .where(
      and(
        eq(systemSettings.key, SETTING_KEY),
        or(eq(systemSettings.portId, portId), isNull(systemSettings.portId)),
      ),
    )
    .limit(1);
  // Stored JSONB shape is the raw boolean (`true` / `false`); the admin-
  // settings PUT handler writes the primitive directly. Only an explicit
  // `false` disables — a missing row / true / unrecognized shape means
  // enabled, matching the registry default.
  if (settingRow[0]?.value === false) return false;
  return true;
}

/**
 * Admin-driven enable. Idempotent — safe to call when already enabled
 * (UPSERT on key+port).
 */
export async function enableResidentialModule(portId: string): Promise<void> {
  await db
    .insert(systemSettings)
    .values({
      key: SETTING_KEY,
      portId,
      value: true,
    })
    .onConflictDoUpdate({
      target: [systemSettings.key, systemSettings.portId],
      set: { value: true, updatedAt: new Date() },
    });
}

/**
 * Admin-driven disable. Does NOT delete any residential rows — those
 * remain in the database and surface again when the module is re-enabled.
 * The frontend warns the operator about the row count before calling this.
 */
export async function disableResidentialModule(portId: string): Promise<void> {
  await db
    .insert(systemSettings)
    .values({
      key: SETTING_KEY,
      portId,
      value: false,
    })
    .onConflictDoUpdate({
      target: [systemSettings.key, systemSettings.portId],
      set: { value: false, updatedAt: new Date() },
    });
}

/**
 * Convenience throw-on-disabled helper for route handlers and services
 * that should hard-fail (404 / NotFound) when the module is off.
 */
export async function assertResidentialModuleEnabled(portId: string): Promise<void> {
  const enabled = await isResidentialModuleEnabled(portId);
  if (!enabled) {
    throw new NotFoundError('Residential module is not enabled for this port.');
  }
}
