import { Prisma } from '@prisma/client';
import { prisma } from '../../config/database';
import { AppError } from '../../middleware/error-handler';
import type { CreatePageBlockInput, UpdatePageBlockInput, ListPageBlocksInput } from './pages.schemas';

const blockSelect = {
  id: true,
  type: true,
  label: true,
  schema: true,
  defaults: true,
  thumbnail: true,
  category: true,
  sortOrder: true,
  createdAt: true,
  updatedAt: true,
} satisfies Prisma.PageBlockSelect;

export const blocksService = {
  async findAll(filters: ListPageBlocksInput) {
    const where: Prisma.PageBlockWhereInput = {};

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

    return prisma.pageBlock.findMany({
      where,
      select: blockSelect,
      orderBy: { sortOrder: 'asc' },
    });
  },

  async findById(id: string) {
    const block = await prisma.pageBlock.findUnique({
      where: { id },
      select: blockSelect,
    });

    if (!block) {
      throw new AppError(404, 'Page block not found', 'BLOCK_NOT_FOUND');
    }

    return block;
  },

  async create(data: CreatePageBlockInput) {
    return prisma.pageBlock.create({
      data: {
        ...data,
        schema: data.schema as unknown as Prisma.InputJsonValue,
        defaults: data.defaults as unknown as Prisma.InputJsonValue,
      },
      select: blockSelect,
    });
  },

  async update(id: string, data: UpdatePageBlockInput) {
    const existing = await prisma.pageBlock.findUnique({ where: { id } });
    if (!existing) {
      throw new AppError(404, 'Page block not found', 'BLOCK_NOT_FOUND');
    }

    const updateData: Prisma.PageBlockUncheckedUpdateInput = { ...data };

    if (data.schema !== undefined) {
      updateData.schema = data.schema as unknown as Prisma.InputJsonValue;
    }
    if (data.defaults !== undefined) {
      updateData.defaults = data.defaults as unknown as Prisma.InputJsonValue;
    }

    return prisma.pageBlock.update({
      where: { id },
      data: updateData,
      select: blockSelect,
    });
  },

  async delete(id: string) {
    const existing = await prisma.pageBlock.findUnique({ where: { id } });
    if (!existing) {
      throw new AppError(404, 'Page block not found', 'BLOCK_NOT_FOUND');
    }

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