import { eq } from "drizzle-orm";

import { jsonFailure, jsonSuccess, readJsonBody } from "@/modules/core/server/api";
import { recordAuditLog } from "@/modules/core/server/audit";
import { requirePermission } from "@/modules/core/server/auth";
import { getDatabase } from "@/modules/core/server/db";
import { organizations } from "@/modules/core/server/schema";
import type { OrganizationStatus } from "@/modules/core/types";
import { RESERVED_WORKSPACE_SLUGS } from "@/modules/shared/lib/workspace-routing";

type RouteContext = {
  params: Promise<{
    id: string;
  }>;
};

const ORGANIZATION_STATUSES: OrganizationStatus[] = ["active", "disabled"];

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}

function readString(source: Record<string, unknown>, key: string): string {
  const value = source[key];
  return typeof value === "string" ? value.trim() : "";
}

function readBoolean(source: Record<string, unknown>, key: string): boolean | null {
  const value = source[key];
  return typeof value === "boolean" ? value : null;
}

function readStatus(value: unknown): OrganizationStatus | null {
  if (typeof value !== "string") {
    return null;
  }

  return ORGANIZATION_STATUSES.find((status) => status === value) ?? null;
}

function isValidSlug(value: string): boolean {
  return /^[a-z0-9][a-z0-9-]{1,47}$/.test(value) && !value.endsWith("-") && !RESERVED_WORKSPACE_SLUGS.has(value);
}

export async function PATCH(request: Request, context: RouteContext): Promise<Response> {
  const { id } = await context.params;
  const auth = await requirePermission("organization:manage", {
    action: "organization.update",
    targetType: "organization",
    targetId: id,
  });

  if (!auth.success) {
    return auth.response;
  }

  const body = await readJsonBody(request);
  if (!isRecord(body)) {
    return jsonFailure("请求数据格式无效");
  }

  const name = readString(body, "name");
  const slug = readString(body, "slug").toLowerCase();
  const oidcIssuerUrl = readString(body, "oidcIssuerUrl");
  const oidcClientId = readString(body, "oidcClientId");
  const oidcClientSecret = readString(body, "oidcClientSecret");
  const oidcScopes = readString(body, "oidcScopes");
  const oidcRedirectUri = readString(body, "oidcRedirectUri");
  const oidcAvatarClaim = readString(body, "oidcAvatarClaim");
  const status = "status" in body ? readStatus(body.status) : null;
  if ("status" in body && !status) {
    return jsonFailure("机构状态无效");
  }
  if ("slug" in body && !slug) {
    return jsonFailure("机构标识不能为空");
  }
  if (slug && !isValidSlug(slug)) {
    return jsonFailure("机构标识仅支持小写字母、数字和连字符，长度 2-48 位，不能以连字符结尾，且不能使用系统路径保留字");
  }
  const registrationEnabled = "registrationEnabled" in body ? readBoolean(body, "registrationEnabled") : null;
  const oidcEnabled = "oidcEnabled" in body ? readBoolean(body, "oidcEnabled") : null;
  const oidcAutoProvision = "oidcAutoProvision" in body ? readBoolean(body, "oidcAutoProvision") : null;
  if ("registrationEnabled" in body && registrationEnabled === null) {
    return jsonFailure("注册开关无效");
  }
  if ("oidcEnabled" in body && oidcEnabled === null) {
    return jsonFailure("OIDC开关无效");
  }
  if ("oidcAutoProvision" in body && oidcAutoProvision === null) {
    return jsonFailure("OIDC自动开户配置无效");
  }
  if (oidcEnabled === true && (!oidcIssuerUrl || !oidcClientId)) {
    return jsonFailure("启用 OIDC 前请填写 Issuer URL 和 Client ID");
  }

  if (
    !name &&
    !slug &&
    !status &&
    registrationEnabled === null &&
    oidcEnabled === null &&
    !oidcIssuerUrl &&
    !oidcClientId &&
    !oidcClientSecret &&
    !oidcScopes &&
    !oidcRedirectUri &&
    !oidcAvatarClaim &&
    oidcAutoProvision === null
  ) {
    return jsonFailure("请至少填写一个要更新的字段");
  }

  const updateValues: {
    name?: string;
    slug?: string;
    status?: OrganizationStatus;
    registrationEnabled?: boolean;
    oidcEnabled?: boolean;
    oidcIssuerUrl?: string;
    oidcClientId?: string;
    oidcClientSecret?: string;
    oidcScopes?: string;
    oidcRedirectUri?: string;
    oidcAvatarClaim?: string;
    oidcAutoProvision?: boolean;
    updatedAt: Date;
  } = {
    updatedAt: new Date(),
  };

  if (name) {
    updateValues.name = name;
  }
  if (slug) {
    updateValues.slug = slug;
  }
  if (status) {
    updateValues.status = status;
  }
  if (registrationEnabled !== null) {
    updateValues.registrationEnabled = registrationEnabled;
  }
  if (oidcEnabled !== null) {
    updateValues.oidcEnabled = oidcEnabled;
  }
  if (oidcIssuerUrl) {
    updateValues.oidcIssuerUrl = oidcIssuerUrl;
  }
  if (oidcClientId) {
    updateValues.oidcClientId = oidcClientId;
  }
  if (oidcClientSecret) {
    updateValues.oidcClientSecret = oidcClientSecret;
  }
  if (oidcScopes) {
    updateValues.oidcScopes = oidcScopes;
  }
  if (oidcRedirectUri) {
    updateValues.oidcRedirectUri = oidcRedirectUri;
  }
  if (oidcAvatarClaim) {
    updateValues.oidcAvatarClaim = oidcAvatarClaim;
  }
  if (oidcAutoProvision !== null) {
    updateValues.oidcAutoProvision = oidcAutoProvision;
  }

  const database = getDatabase();
  try {
    const rows = await database.update(organizations).set(updateValues).where(eq(organizations.id, id)).returning();
    const organization = rows[0];
    if (!organization) {
      return jsonFailure("机构不存在", 404);
    }

    await recordAuditLog({
      actor: auth.context.account,
      organizationId: organization.id,
      action: "organization.update",
      targetType: "organization",
      targetId: organization.id,
      result: "success",
      reason: `更新机构：${organization.name}`,
    });

    return jsonSuccess("机构已更新", { organization });
  } catch (error) {
    const message = error instanceof Error ? error.message : "";
    if (message.includes("organizations_slug_unique")) {
      return jsonFailure("机构标识已存在", 409);
    }

    return jsonFailure("机构更新失败", 500);
  }
}

export async function DELETE(_request: Request, context: RouteContext): Promise<Response> {
  const { id } = await context.params;
  const auth = await requirePermission("organization:manage", {
    action: "organization.disable",
    targetType: "organization",
    targetId: id,
  });

  if (!auth.success) {
    return auth.response;
  }

  const database = getDatabase();
  const rows = await database
    .update(organizations)
    .set({ status: "disabled", updatedAt: new Date() })
    .where(eq(organizations.id, id))
    .returning();
  const organization = rows[0];
  if (!organization) {
    return jsonFailure("机构不存在", 404);
  }

  await recordAuditLog({
    actor: auth.context.account,
    organizationId: organization.id,
    action: "organization.disable",
    targetType: "organization",
    targetId: organization.id,
    result: "success",
    reason: `停用机构：${organization.name}`,
  });

  return jsonSuccess("机构已停用", { organization });
}
