import { Elysia, t } from "elysia";
import { authMiddleware } from "../middlewares/auth";
import { branchService } from "../services/branch";
import { companyService } from "../services/company";

export const branchController = new Elysia({ prefix: "/branches" })
  // Все роуты требуют авторизации
  .use(authMiddleware)
  // GET /branches - получить филиалы пользователя
  .get("/my", async ({ currentUser }) => {
    const branches = await branchService.findByUserId(currentUser.id);
    return { branches };
  })
  // GET /branches/:id - получить филиал по ID
  .get("/:id", async ({ params, status }) => {
    const { id } = params;

    const branch = await branchService.findById(id);

    if (!branch) {
      return status(404, "Branch not found");
    }

    return { branch };
  })
  // GET /branches/:id/users - получить пользователей филиала
  .get("/:id/users", async ({ params, status }) => {
    const { id } = params;

    // Проверить существование филиала
    const branch = await branchService.findById(id);

    if (!branch) {
      return status(404, "Branch not found");
    }

    const users = await branchService.getUsersByBranchId(id);

    return { users };
  })
  // POST /branches - создать филиал
  .post(
    "/",
    async ({ body, status }) => {
      const { companyId, name, address, city, country } = body as {
        companyId: string;
        name: string;
        address?: string;
        city?: string;
        country?: string;
      };

      // Проверить существование компании
      const company = await companyService.findById(companyId);

      if (!company) {
        return status(404, "Company not found");
      }

      const branch = await branchService.create({
        companyId,
        name,
        address,
        city,
        country,
      });

      return { branch };
    },
    {
      body: t.Object({
        companyId: t.String({ format: "uuid" }),
        name: t.String({ minLength: 1, maxLength: 255 }),
        address: t.Optional(t.String({ maxLength: 500 })),
        city: t.Optional(t.String({ maxLength: 100 })),
        country: t.Optional(t.String({ maxLength: 100 })),
      }),
    }
  )
  // PATCH /branches/:id - обновить филиал
  .patch(
    "/:id",
    async ({ params, body, status }) => {
      const { id } = params;
      const { name, address, city, country } = body as {
        name?: string;
        address?: string;
        city?: string;
        country?: string;
      };

      // Проверить существование филиала
      const branch = await branchService.findById(id);

      if (!branch) {
        return status(404, "Branch not found");
      }

      const updatedBranch = await branchService.update(id, {
        name,
        address,
        city,
        country,
      });

      return { branch: updatedBranch };
    },
    {
      body: t.Object({
        name: t.Optional(t.String({ minLength: 1, maxLength: 255 })),
        address: t.Optional(t.String({ maxLength: 500 })),
        city: t.Optional(t.String({ maxLength: 100 })),
        country: t.Optional(t.String({ maxLength: 100 })),
      }),
    }
  )
  // DELETE /branches/:id - удалить филиал
  .delete("/:id", async ({ params, status }) => {
    const { id } = params;

    // Проверить существование филиала
    const branch = await branchService.findById(id);

    if (!branch) {
      return status(404, "Branch not found");
    }

    await branchService.delete(id);

    return { message: "Branch deleted successfully" };
  })
  // POST /branches/:id/users - привязать пользователя к филиалу
  .post(
    "/:id/users",
    async ({ params, body, status }) => {
      const { id } = params;
      const { userId } = body as { userId: string };

      // Проверить существование филиала
      const branch = await branchService.findById(id);

      if (!branch) {
        return status(404, "Branch not found");
      }

      try {
        await branchService.assignUserToBranch(userId, id);
        return { message: "User assigned to branch successfully" };
      } catch (error) {
        return status(409, "User is already assigned to this branch");
      }
    },
    {
      body: t.Object({
        userId: t.String({ format: "uuid" }),
      }),
    }
  )
  // DELETE /branches/:id/users/:userId - отвязать пользователя от филиала
  .delete("/:id/users/:userId", async ({ params, status }) => {
    const { id, userId } = params;

    // Проверить существование филиала
    const branch = await branchService.findById(id);

    if (!branch) {
      return status(404, "Branch not found");
    }

    await branchService.removeUserFromBranch(userId, id);

    return { message: "User removed from branch successfully" };
  })
  // POST /branches/:id/select - установить филиал как текущий для пользователя
  .post("/:id/select", async ({ params, currentUser, status }) => {
    const { id } = params;

    try {
      const updatedUser = await branchService.setUserCurrentBranch(
        currentUser.id,
        id
      );

      return {
        message: "Current branch updated successfully",
        currentBranchId: updatedUser.currentBranchId,
      };
    } catch (error) {
      if (error instanceof Error) {
        return status(400, error.message);
      }
      return status(500, "Failed to update current branch");
    }
  });
