import { eq } from "drizzle-orm";

import { getDatabase } from "@/modules/core/server/db";
import { systemSettings } from "@/modules/core/server/schema";
import type { SystemSettings } from "@/modules/core/types";

const GLOBAL_SETTINGS_ID = "global";

type SystemSettingsRow = typeof systemSettings.$inferSelect;

export type SystemSettingsUpdate = {
  registrationEnabled?: boolean;
  oidcEnabled?: boolean;
  oidcIssuerUrl?: string;
  oidcClientId?: string;
  oidcClientSecret?: string;
  oidcScopes?: string;
  oidcRedirectUri?: string;
  oidcAvatarClaim?: string;
  oidcAutoProvision?: boolean;
};

function toSystemSettings(row: SystemSettingsRow): SystemSettings {
  return {
    id: row.id,
    registrationEnabled: row.registrationEnabled,
    oidcEnabled: row.oidcEnabled,
    oidcIssuerUrl: row.oidcIssuerUrl,
    oidcClientId: row.oidcClientId,
    oidcHasClientSecret: row.oidcClientSecret.length > 0,
    oidcScopes: row.oidcScopes,
    oidcRedirectUri: row.oidcRedirectUri,
    oidcAvatarClaim: row.oidcAvatarClaim,
    oidcAutoProvision: row.oidcAutoProvision,
    updatedAt: row.updatedAt.toISOString(),
  };
}

async function ensureSystemSettingsRow(): Promise<SystemSettingsRow> {
  const database = getDatabase();
  const existingRows = await database
    .select()
    .from(systemSettings)
    .where(eq(systemSettings.id, GLOBAL_SETTINGS_ID))
    .limit(1);
  const existing = existingRows[0];
  if (existing) {
    return existing;
  }

  const createdRows = await database
    .insert(systemSettings)
    .values({ id: GLOBAL_SETTINGS_ID })
    .onConflictDoNothing()
    .returning();
  const created = createdRows[0];
  if (created) {
    return created;
  }

  const fallbackRows = await database
    .select()
    .from(systemSettings)
    .where(eq(systemSettings.id, GLOBAL_SETTINGS_ID))
    .limit(1);
  const fallback = fallbackRows[0];
  if (!fallback) {
    throw new Error("系统配置初始化失败");
  }

  return fallback;
}

export async function ensureSystemSettings(): Promise<void> {
  await ensureSystemSettingsRow();
}

export async function getSystemSettings(): Promise<SystemSettings> {
  const row = await ensureSystemSettingsRow();
  return toSystemSettings(row);
}

export async function updateSystemSettings(input: SystemSettingsUpdate): Promise<SystemSettings> {
  const database = getDatabase();
  await ensureSystemSettingsRow();

  const updateValues: SystemSettingsUpdate & { updatedAt: Date } = {
    updatedAt: new Date(),
  };
  if (input.registrationEnabled !== undefined) {
    updateValues.registrationEnabled = input.registrationEnabled;
  }
  if (input.oidcEnabled !== undefined) {
    updateValues.oidcEnabled = input.oidcEnabled;
  }
  if (input.oidcIssuerUrl !== undefined) {
    updateValues.oidcIssuerUrl = input.oidcIssuerUrl;
  }
  if (input.oidcClientId !== undefined) {
    updateValues.oidcClientId = input.oidcClientId;
  }
  if (input.oidcClientSecret !== undefined && input.oidcClientSecret.length > 0) {
    updateValues.oidcClientSecret = input.oidcClientSecret;
  }
  if (input.oidcScopes !== undefined) {
    updateValues.oidcScopes = input.oidcScopes;
  }
  if (input.oidcRedirectUri !== undefined) {
    updateValues.oidcRedirectUri = input.oidcRedirectUri;
  }
  if (input.oidcAvatarClaim !== undefined) {
    updateValues.oidcAvatarClaim = input.oidcAvatarClaim;
  }
  if (input.oidcAutoProvision !== undefined) {
    updateValues.oidcAutoProvision = input.oidcAutoProvision;
  }

  const rows = await database
    .update(systemSettings)
    .set(updateValues)
    .where(eq(systemSettings.id, GLOBAL_SETTINGS_ID))
    .returning();
  const row = rows[0];
  if (!row) {
    throw new Error("系统配置不存在");
  }

  return toSystemSettings(row);
}
