import type {
  SocialFeedDashboard,
  SocialFeedDashboardCreate,
  SocialFeedDashboardUpdate
} from '@nexumi/shared';
import type { SocialFeed } from '@prisma/client';
import { prisma } from '../prisma';
import { assertPremiumLimit, PremiumLimitError } from '../premium';

export class FeedPremiumError extends Error {
  constructor(public readonly code: 'premium_limit' | 'premium_feature') {
    super(code);
  }
}

function toDashboard(feed: SocialFeed): SocialFeedDashboard {
  return {
    id: feed.id,
    type: feed.type as SocialFeedDashboard['type'],
    sourceId: feed.sourceId,
    channelId: feed.channelId,
    rolePingId: feed.rolePingId ?? '',
    template: feed.template,
    enabled: feed.enabled
  };
}

export async function listFeeds(guildId: string): Promise<SocialFeedDashboard[]> {
  const feeds = await prisma.socialFeed.findMany({
    where: { guildId },
    orderBy: { createdAt: 'asc' }
  });
  return feeds.map(toDashboard);
}

export async function createFeed(
  guildId: string,
  input: SocialFeedDashboardCreate
): Promise<SocialFeedDashboard> {
  await prisma.guild.upsert({ where: { id: guildId }, update: {}, create: { id: guildId } });
  const currentCount = await prisma.socialFeed.count({ where: { guildId } });
  try {
    await assertPremiumLimit(prisma, guildId, 'feeds', currentCount);
  } catch (error) {
    if (error instanceof PremiumLimitError) {
      throw new FeedPremiumError(error.code === 'feature_disabled' ? 'premium_feature' : 'premium_limit');
    }
    throw error;
  }
  const feed = await prisma.socialFeed.create({
    data: {
      guildId,
      type: input.type,
      sourceId: input.sourceId,
      channelId: input.channelId,
      rolePingId: input.rolePingId || null,
      template: input.template ?? null,
      enabled: input.enabled
    }
  });
  return toDashboard(feed);
}

export async function updateFeed(
  guildId: string,
  feedId: string,
  patch: SocialFeedDashboardUpdate
): Promise<SocialFeedDashboard | null> {
  const existing = await prisma.socialFeed.findFirst({ where: { id: feedId, guildId } });
  if (!existing) {
    return null;
  }

  const { rolePingId, ...rest } = patch;
  const updated = await prisma.socialFeed.update({
    where: { id: feedId },
    data: {
      ...rest,
      ...(rolePingId !== undefined ? { rolePingId: rolePingId === '' ? null : rolePingId } : {})
    }
  });
  return toDashboard(updated);
}

export async function deleteFeed(guildId: string, feedId: string): Promise<boolean> {
  const existing = await prisma.socialFeed.findFirst({ where: { id: feedId, guildId } });
  if (!existing) {
    return false;
  }
  await prisma.socialFeed.delete({ where: { id: feedId } });
  return true;
}
