import { prisma } from '@/db';
import { BoxWhereInput } from '@/generated/prisma/models';
import { parseError } from '@/lib/errors';
import { DB_TABLE, LOG_ACTION } from '@/types/enum';
import { authMiddleware } from '@lib/middleware';
import { createServerFn } from '@tanstack/react-start';
import { boxListSchema, createBoxSchema, updateBoxSchema } from './box.schema';
import { createAuditLog } from './repository';

export const getAllBox = createServerFn({ method: 'GET' })
  .middleware([authMiddleware])
  .validator(boxListSchema)
  .handler(async ({ data }) => {
    try {
      const { page, limit, keyword } = data;
      const skip = (page - 1) * limit;

      const where: BoxWhereInput = {
        OR: [
          {
            name: {
              contains: keyword,
              mode: 'insensitive',
            },
          },
        ],
      };

      const [list, total]: [any[], number] = await prisma.$transaction([
        prisma.box.findMany({
          where,
          orderBy: { createdAt: 'desc' },
          include: {
            _count: {
              select: {
                items: true,
              },
            },
            house: {
              select: {
                id: true,
                name: true,
                color: true,
              },
            },
            user: {
              select: {
                id: true,
                name: true,
                email: true,
                image: true,
                role: true,
              },
            },
          },
          omit: {
            createrId: true,
            houseId: true,
          },
          take: limit,
          skip,
        }),
        prisma.box.count({ where }),
      ]);

      const totalPage = Math.ceil(+total / limit);

      return {
        result: list,
        pagination: {
          currentPage: page,
          totalPage,
          totalItem: total,
        },
      };
    } catch (error) {
      console.error(error);
      const { message, code } = parseError(error);
      throw { message, code };
    }
  });

export const createBox = createServerFn({ method: 'POST' })
  .middleware([authMiddleware])
  .validator(createBoxSchema)
  .handler(async ({ data, context: { user } }) => {
    try {
      const { name, description, color, tags, houseId } = data;

      const result = await prisma.box.create({
        data: {
          name,
          description,
          color,
          houseId,
          tags,
          createrId: user.id,
        },
      });

      if (!result) throw Error('Failed to create box');

      await createAuditLog({
        action: LOG_ACTION.CREATE,
        tableName: DB_TABLE.BOX,
        recordId: result.id,
        oldValue: '',
        newValue: JSON.stringify(result),
        userId: user.id,
      });

      return result;
    } catch (error) {
      console.error(error);
      const { message, code } = parseError(error);
      throw { message, code };
    }
  });

export const updateBoxAdmin = createServerFn({ method: 'POST' })
  .middleware([authMiddleware])
  .validator(updateBoxSchema)
  .handler(async ({ data, context: { user } }) => {
    try {
      const { id, name, description, color, tags } = data;
    } catch (error) {
      console.error(error);
      const { message, code } = parseError(error);
      throw { message, code };
    }
  });
