import { and, 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 { accounts, joinRequests, memberships, roles } from "@/modules/core/server/schema";

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

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() : "";
}

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

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

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

  const decision = readString(body, "decision");
  if (decision !== "approved" && decision !== "rejected") {
    return jsonFailure("审批结果无效");
  }

  const database = getDatabase();
  const reviewed = await database.transaction(async (transaction) => {
    const requestRows = await transaction
      .select()
      .from(joinRequests)
      .where(eq(joinRequests.id, id))
      .limit(1);
    const joinRequest = requestRows[0];
    if (!joinRequest) {
      return null;
    }

    const activeOrganizationId = auth.context.organization?.id;
    if (activeOrganizationId && joinRequest.organizationId !== activeOrganizationId) {
      throw new Error("不能审批其他机构的申请");
    }

    if (joinRequest.status !== "pending") {
      throw new Error("申请已处理");
    }

    const roleId = readString(body, "roleId");
    if (decision === "approved" && !roleId) {
      throw new Error("请选择审批角色");
    }

    if (decision === "approved") {
      const roleRows = await transaction
        .select()
        .from(roles)
        .where(and(eq(roles.id, roleId), eq(roles.organizationId, joinRequest.organizationId)))
        .limit(1);
      const role = roleRows[0];
      if (!role) {
        throw new Error("审批角色不存在");
      }

      await transaction
        .insert(memberships)
        .values({
          accountId: joinRequest.accountId,
          organizationId: joinRequest.organizationId,
          roleId: role.id,
          status: "active",
        })
        .onConflictDoUpdate({
          target: [memberships.accountId, memberships.organizationId],
          set: {
            roleId: role.id,
            status: "active",
            updatedAt: new Date(),
          },
        });
      await transaction
        .update(accounts)
        .set({ status: "active", updatedAt: new Date() })
        .where(eq(accounts.id, joinRequest.accountId));
    }

    const updatedRows = await transaction
      .update(joinRequests)
      .set({
        status: decision,
        reviewedByAccountId: auth.context.account.id,
        reviewedAt: new Date(),
      })
      .where(eq(joinRequests.id, joinRequest.id))
      .returning();
    const updated = updatedRows[0];
    if (!updated) {
      throw new Error("申请审批失败");
    }

    return updated;
  });

  if (!reviewed) {
    return jsonFailure("加入申请不存在", 404);
  }

  await recordAuditLog({
    actor: auth.context.account,
    organizationId: reviewed.organizationId,
    action: "joinRequest.review",
    targetType: "joinRequest",
    targetId: reviewed.id,
    result: "success",
    reason: decision === "approved" ? "通过加入申请" : "拒绝加入申请",
  });

  return jsonSuccess("加入申请已处理", { joinRequest: reviewed });
}
