import { prisma } from '../../../config/database';
import type { CreateSmsTemplateInput, UpdateSmsTemplateInput } from './sms-templates.schemas';

/** Names of templates seeded by the system — cannot be deleted */
const SYSTEM_TEMPLATE_NAMES = ['shift-reminder', 'shift-signup-confirm', 'volunteer-welcome'];

/** Extract {var} placeholder names from a template string */
function extractVariables(template: string): string[] {
  const vars: string[] = [];
  const regex = /\{(\w+)\}/g;
  let match;
  while ((match = regex.exec(template)) !== null) {
    if (!vars.includes(match[1])) vars.push(match[1]);
  }
  return vars;
}

export const smsTemplatesService = {
  async findAll(params: {
    page?: number;
    limit?: number;
    search?: string;
    category?: string;
    isFavorite?: string;
  }) {
    const page = params.page || 1;
    const limit = params.limit || 50;
    const skip = (page - 1) * limit;

    const where: Record<string, unknown> = {};

    if (params.search) {
      where.OR = [
        { name: { contains: params.search, mode: 'insensitive' } },
        { description: { contains: params.search, mode: 'insensitive' } },
        { template: { contains: params.search, mode: 'insensitive' } },
      ];
    }

    if (params.category) {
      where.category = params.category;
    }

    if (params.isFavorite === 'true') {
      where.isFavorite = true;
    }

    const [items, total] = await Promise.all([
      prisma.smsMessageTemplate.findMany({
        where,
        orderBy: [{ isFavorite: 'desc' }, { name: 'asc' }],
        skip,
        take: limit,
        include: {
          createdByUser: { select: { id: true, name: true, email: true } },
        },
      }),
      prisma.smsMessageTemplate.count({ where }),
    ]);

    // Enrich with computed fields
    const enriched = items.map((t) => ({
      ...t,
      variables: extractVariables(t.template),
      isSystem: SYSTEM_TEMPLATE_NAMES.includes(t.name) && t.createdByUserId === null,
    }));

    return { items: enriched, total, page, limit };
  },

  async findById(id: string) {
    const t = await prisma.smsMessageTemplate.findUnique({
      where: { id },
      include: {
        createdByUser: { select: { id: true, name: true, email: true } },
      },
    });
    if (!t) return null;
    return {
      ...t,
      variables: extractVariables(t.template),
      isSystem: SYSTEM_TEMPLATE_NAMES.includes(t.name) && t.createdByUserId === null,
    };
  },

  async create(data: CreateSmsTemplateInput, userId: string) {
    // Check for duplicate name (SmsNotificationService looks up by name)
    const existing = await prisma.smsMessageTemplate.findFirst({
      where: { name: data.name },
      select: { id: true },
    });
    if (existing) throw new Error('A template with this name already exists');

    return prisma.smsMessageTemplate.create({
      data: {
        name: data.name,
        template: data.template,
        description: data.description ?? null,
        category: data.category ?? null,
        isFavorite: data.isFavorite ?? false,
        createdByUserId: userId,
      },
    });
  },

  async update(id: string, data: UpdateSmsTemplateInput) {
    const existing = await prisma.smsMessageTemplate.findUnique({
      where: { id },
      select: { id: true, name: true },
    });
    if (!existing) throw new Error('Template not found');

    // If renaming, check for duplicate
    if (data.name && data.name !== existing.name) {
      const dup = await prisma.smsMessageTemplate.findFirst({
        where: { name: data.name, NOT: { id } },
        select: { id: true },
      });
      if (dup) throw new Error('A template with this name already exists');
    }

    return prisma.smsMessageTemplate.update({ where: { id }, data });
  },

  async delete(id: string) {
    const t = await prisma.smsMessageTemplate.findUnique({
      where: { id },
      select: { name: true, createdByUserId: true },
    });
    if (!t) throw new Error('Template not found');
    if (SYSTEM_TEMPLATE_NAMES.includes(t.name) && t.createdByUserId === null) {
      throw new Error('System templates cannot be deleted');
    }

    await prisma.smsMessageTemplate.delete({ where: { id } });
  },

  async toggleFavorite(id: string) {
    const t = await prisma.smsMessageTemplate.findUnique({
      where: { id },
      select: { isFavorite: true },
    });
    if (!t) throw new Error('Template not found');

    return prisma.smsMessageTemplate.update({
      where: { id },
      data: { isFavorite: !t.isFavorite },
    });
  },

  extractVariables,
};
