import type {
  SelfRoleEntry,
  SelfRolePanelDashboard,
  SelfRolePanelDashboardCreate,
  SelfRolePanelDashboardUpdate
} from '@nexumi/shared';
import type { Prisma, SelfRolePanel } from '@prisma/client';
import { prisma } from '../prisma';

function toRolesArray(raw: unknown): SelfRoleEntry[] {
  if (!Array.isArray(raw)) {
    return [];
  }
  return raw.filter(
    (entry): entry is SelfRoleEntry =>
      Boolean(entry) && typeof entry === 'object' && typeof (entry as SelfRoleEntry).roleId === 'string'
  );
}

function toDashboard(panel: SelfRolePanel): SelfRolePanelDashboard {
  return {
    id: panel.id,
    channelId: panel.channelId,
    title: panel.title,
    description: panel.description,
    mode: panel.mode as SelfRolePanelDashboard['mode'],
    behavior: panel.behavior as SelfRolePanelDashboard['behavior'],
    roles: toRolesArray(panel.roles),
    expiresAt: panel.expiresAt?.toISOString() ?? null
  };
}

export async function listSelfRolePanels(guildId: string): Promise<SelfRolePanelDashboard[]> {
  const panels = await prisma.selfRolePanel.findMany({
    where: { guildId },
    orderBy: { createdAt: 'desc' }
  });
  return panels.map(toDashboard);
}

export async function createSelfRolePanel(
  guildId: string,
  input: SelfRolePanelDashboardCreate
): Promise<SelfRolePanelDashboard> {
  await prisma.guild.upsert({ where: { id: guildId }, update: {}, create: { id: guildId } });
  const panel = await prisma.selfRolePanel.create({
    data: {
      guildId,
      channelId: input.channelId,
      title: input.title,
      description: input.description ?? null,
      mode: input.mode,
      behavior: input.behavior,
      roles: input.roles as unknown as Prisma.InputJsonValue,
      expiresAt: input.expiresAt ? new Date(input.expiresAt) : null
    }
  });
  return toDashboard(panel);
}

export async function updateSelfRolePanel(
  guildId: string,
  panelId: string,
  patch: SelfRolePanelDashboardUpdate
): Promise<SelfRolePanelDashboard | null> {
  const existing = await prisma.selfRolePanel.findFirst({ where: { id: panelId, guildId } });
  if (!existing) {
    return null;
  }

  const updated = await prisma.selfRolePanel.update({
    where: { id: panelId },
    data: {
      ...(patch.channelId !== undefined ? { channelId: patch.channelId } : {}),
      ...(patch.title !== undefined ? { title: patch.title } : {}),
      ...(patch.description !== undefined ? { description: patch.description } : {}),
      ...(patch.mode !== undefined ? { mode: patch.mode } : {}),
      ...(patch.behavior !== undefined ? { behavior: patch.behavior } : {}),
      ...(patch.roles !== undefined ? { roles: patch.roles as unknown as Prisma.InputJsonValue } : {}),
      ...(patch.expiresAt !== undefined
        ? { expiresAt: patch.expiresAt ? new Date(patch.expiresAt) : null }
        : {})
    }
  });
  return toDashboard(updated);
}

export async function deleteSelfRolePanel(guildId: string, panelId: string): Promise<boolean> {
  const result = await prisma.selfRolePanel.deleteMany({ where: { id: panelId, guildId } });
  return result.count > 0;
}
