import { z } from "zod";
import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";

import { auth } from "@/auth";
import { prisma } from "@/lib/prisma";

import { createBoardSchema, updateBoardSchema, getBoardsSchema } from "../schemas";

const app = new Hono()
  .post(
    "/",
    zValidator("json", createBoardSchema),
    async (c) => {
      const session = await auth();
      const { name, description, projectId } = c.req.valid("json");

      if (!session?.user?.email) {
        return c.json({ error: "Unauthorized" }, 401);
      }

      const currentUser = await prisma.user.findUnique({
        where: { email: session.user.email },
      });

      if (!currentUser) {
        return c.json({ error: "User not found" }, 404);
      }

      // Check if project exists and user has access
      const project = await prisma.project.findUnique({
        where: { id: projectId },
      });

      if (!project) {
        return c.json({ error: "Project not found" }, 404);
      }

      // Check if user is a member of the workspace
      const member = await prisma.member.findFirst({
        where: {
          workspaceId: project.workspaceId,
          userId: currentUser.id,
        },
      });

      if (!member) {
        return c.json({ error: "Unauthorized" }, 401);
      }

      // Get the highest position to place the new board at the end
      const maxPosition = await prisma.board.findFirst({
        where: { projectId },
        orderBy: { position: 'desc' },
        select: { position: true },
      });

      const position = maxPosition ? maxPosition.position + 1000 : 1000;

      // Create the board
      const board = await prisma.board.create({
        data: {
          name,
          description,
          projectId,
          position,
        },
      });

      return c.json({ data: board });
    }
  )
  .get(
    "/",
    zValidator("query", getBoardsSchema),
    async (c) => {
      const session = await auth();
      const { projectId } = c.req.valid("query");

      if (!session?.user?.email) {
        return c.json({ error: "Unauthorized" }, 401);
      }

      const currentUser = await prisma.user.findUnique({
        where: { email: session.user.email },
      });

      if (!currentUser) {
        return c.json({ error: "User not found" }, 404);
      }

      // Check if project exists and user has access
      const project = await prisma.project.findUnique({
        where: { id: projectId },
      });

      if (!project) {
        return c.json({ error: "Project not found" }, 404);
      }

      // Check if user is a member of the workspace
      const member = await prisma.member.findFirst({
        where: {
          workspaceId: project.workspaceId,
          userId: currentUser.id,
        },
      });

      if (!member) {
        return c.json({ error: "Unauthorized" }, 401);
      }

      // Get all boards for the project
      const boards = await prisma.board.findMany({
        where: { projectId },
        orderBy: { position: 'asc' },
        include: {
          tasks: {
            select: {
              id: true,
              name: true,
              status: true,
            },
          },
        },
      });

      return c.json({ 
        data: {
          documents: boards,
          total: boards.length
        } 
      });
    }
  )
  .get("/:boardId", async (c) => {
    const session = await auth();
    const { boardId } = c.req.param();

    if (!session?.user?.email) {
      return c.json({ error: "Unauthorized" }, 401);
    }

    const currentUser = await prisma.user.findUnique({
      where: { email: session.user.email },
    });

    if (!currentUser) {
      return c.json({ error: "User not found" }, 404);
    }

    // Get the board with project info
    const board = await prisma.board.findUnique({
      where: { id: boardId },
      include: {
        project: true,
        tasks: {
          select: {
            id: true,
            name: true,
            status: true,
          },
        },
      },
    });

    if (!board) {
      return c.json({ error: "Board not found" }, 404);
    }

    // Check if user is a member of the workspace
    const member = await prisma.member.findFirst({
      where: {
        workspaceId: board.project.workspaceId,
        userId: currentUser.id,
      },
    });

    if (!member) {
      return c.json({ error: "Unauthorized" }, 401);
    }

    return c.json({ data: board });
  })
  .patch(
    "/:boardId",
    zValidator("json", updateBoardSchema),
    async (c) => {
      const session = await auth();
      const { boardId } = c.req.param();
      const { name, description, position } = c.req.valid("json");

      if (!session?.user?.email) {
        return c.json({ error: "Unauthorized" }, 401);
      }

      const currentUser = await prisma.user.findUnique({
        where: { email: session.user.email },
      });

      if (!currentUser) {
        return c.json({ error: "User not found" }, 404);
      }

      // Get the existing board
      const existingBoard = await prisma.board.findUnique({
        where: { id: boardId },
        include: { project: true },
      });

      if (!existingBoard) {
        return c.json({ error: "Board not found" }, 404);
      }

      // Check if user is a member of the workspace
      const member = await prisma.member.findFirst({
        where: {
          workspaceId: existingBoard.project.workspaceId,
          userId: currentUser.id,
        },
      });

      if (!member) {
        return c.json({ error: "Unauthorized" }, 401);
      }

      // Update the board
      const board = await prisma.board.update({
        where: { id: boardId },
        data: {
          name: name || existingBoard.name,
          description: description !== undefined ? description : existingBoard.description,
          position: position !== undefined ? position : existingBoard.position,
        },
      });

      return c.json({ data: board });
    }
  )
  .delete("/:boardId", async (c) => {
    const session = await auth();
    const { boardId } = c.req.param();

    if (!session?.user?.email) {
      return c.json({ error: "Unauthorized" }, 401);
    }

    const currentUser = await prisma.user.findUnique({
      where: { email: session.user.email },
    });

    if (!currentUser) {
      return c.json({ error: "User not found" }, 404);
    }

    // Get the existing board
    const existingBoard = await prisma.board.findUnique({
      where: { id: boardId },
      include: { project: true },
    });

    if (!existingBoard) {
      return c.json({ error: "Board not found" }, 404);
    }

    // Check if user is a member of the workspace
    const member = await prisma.member.findFirst({
      where: {
        workspaceId: existingBoard.project.workspaceId,
        userId: currentUser.id,
      },
    });

    if (!member) {
      return c.json({ error: "Unauthorized" }, 401);
    }

    // Delete the board and move its tasks to the project (boardId = null)
    await prisma.$transaction(async (tx) => {
      // Move tasks to project level (remove board assignment)
      await tx.task.updateMany({
        where: { boardId },
        data: { boardId: null },
      });

      // Delete the board
      await tx.board.delete({
        where: { id: boardId },
      });
    });

    return c.json({ data: { id: boardId } });
  });

export default app; 