import { ActivityLog } from "@/db/models";
import type { AuthUser } from "@/middleware/auth";
import { isMysqlActive } from "@/db/activeDatabase";
import { createId } from "@/db/ids";
import type { RowDataPacket } from "mysql2/promise";
import { connectMysql, mysqlPool, sqlExecute, sqlQuery } from "@/db/mysql/pool";

async function ensureMysql() {
  try {
    mysqlPool();
  } catch {
    await connectMysql();
  }
}

export async function logActivity(params: {
  actor: Pick<AuthUser, "id" | "email" | "fullName">;
  action: string;
  entityType: string;
  entityId?: string;
  meta?: Record<string, unknown>;
}) {
  try {
    if (isMysqlActive()) {
      await ensureMysql();
      await sqlExecute(
        `INSERT INTO activity_logs
          (id, actor_id, actor_email, actor_name, action, entity_type, entity_id, meta, created_at)
         VALUES (?,?,?,?,?,?,?,?,?)`,
        [
          createId(),
          params.actor.id,
          params.actor.email,
          params.actor.fullName || "",
          params.action,
          params.entityType,
          params.entityId ?? null,
          params.meta ? JSON.stringify(params.meta) : null,
          new Date(),
        ],
      );
      return;
    }

    await ActivityLog.create({
      actorId: params.actor.id,
      actorEmail: params.actor.email,
      actorName: params.actor.fullName || "",
      action: params.action,
      entityType: params.entityType,
      entityId: params.entityId,
      meta: params.meta,
    });
  } catch (err) {
    console.error("[activity-log]", err);
  }
}

export async function listActivityMysql(opts: {
  actorId?: string;
  action?: string | string[];
  take?: number;
}) {
  await ensureMysql();
  const where: string[] = [];
  const params: unknown[] = [];
  if (opts.actorId) {
    where.push("actor_id = ?");
    params.push(opts.actorId);
  }
  if (opts.action) {
    const actions = Array.isArray(opts.action) ? opts.action : [opts.action];
    if (actions.length === 1) {
      where.push("action = ?");
      params.push(actions[0]);
    } else if (actions.length > 1) {
      where.push(`action IN (${actions.map(() => "?").join(",")})`);
      params.push(...actions);
    }
  }
  const take = Math.min(Math.max(opts.take ?? 300, 1), 500);
  params.push(take);
  const rows = await sqlQuery<RowDataPacket[]>(
    `SELECT * FROM activity_logs
     ${where.length ? `WHERE ${where.join(" AND ")}` : ""}
     ORDER BY created_at DESC
     LIMIT ?`,
    params,
  );
  return rows.map((r) => {
    let meta: Record<string, unknown> | undefined;
    if (r.meta != null) {
      if (typeof r.meta === "object" && !Buffer.isBuffer(r.meta)) {
        meta = r.meta as Record<string, unknown>;
      } else if (typeof r.meta === "string") {
        try {
          meta = JSON.parse(r.meta);
        } catch {
          meta = undefined;
        }
      }
    }
    return {
      id: String(r.id),
      actorId: String(r.actor_id),
      actorEmail: String(r.actor_email),
      actorName: String(r.actor_name || ""),
      action: String(r.action),
      entityType: String(r.entity_type),
      entityId: r.entity_id == null ? undefined : String(r.entity_id),
      meta,
      createdAt: new Date(r.created_at),
    };
  });
}

/** Finance-related activity actions visible to FINANCE_ADMIN. */
export const FINANCE_ACTIVITY_ACTIONS = [
  "withdrawal.approve",
  "withdrawal.reject",
  "refund.process",
  "wallet.topup.approve",
  "wallet.topup.reject",
  "wallet.adjust",
] as const;
