import { FastifyInstance } from "fastify";
import { requirePermission } from "../../middleware/auth";
import { logAudit } from "../../services/audit";
import { success, error, parseId, paginated } from "../../utils/response";
import { parsePagination, buildPaginationMeta } from "../../utils/pagination";
import { parseBody } from "../../schemas/common";
import {
  CreateIssuedOrderSchema,
  UpdateIssuedOrderSchema,
} from "../../schemas/issued-orders.schema";
import {
  listIssuedOrders,
  getIssuedOrder,
  createIssuedOrder,
  updateIssuedOrder,
  deleteIssuedOrder,
  getNextIssuedOrderNumberPreview,
} from "../../services/issued-orders.service";

export default async function issuedOrdersRoutes(fastify: FastifyInstance) {
  // GET /api/admin/issued-orders
  fastify.get(
    "/",
    { preHandler: requirePermission("orders.view") },
    async (request, reply) => {
      const query = request.query as Record<string, unknown>;
      const { page, limit, skip, order, search } = parsePagination(query);
      const result = await listIssuedOrders({
        page,
        limit,
        skip,
        sort: String(query.sort || ""),
        order,
        search,
        status: query.status ? String(query.status) : undefined,
        customer_id: query.customer_id ? Number(query.customer_id) : undefined,
      });
      return paginated(
        reply,
        result.data,
        buildPaginationMeta(result.total, page, limit),
      );
    },
  );

  // GET /api/admin/issued-orders/next-number
  fastify.get(
    "/next-number",
    { preHandler: requirePermission("orders.create") },
    async (_request, reply) => {
      return success(reply, await getNextIssuedOrderNumberPreview());
    },
  );

  // GET /api/admin/issued-orders/:id
  fastify.get<{ Params: { id: string } }>(
    "/:id",
    { preHandler: requirePermission("orders.view") },
    async (request, reply) => {
      const id = parseId(request.params.id, reply);
      if (id === null) return;
      const order = await getIssuedOrder(id);
      if (!order) return error(reply, "Objednávka nenalezena", 404);
      return success(reply, order);
    },
  );

  // POST /api/admin/issued-orders
  fastify.post(
    "/",
    { preHandler: requirePermission("orders.create") },
    async (request, reply) => {
      const parsed = parseBody(CreateIssuedOrderSchema, request.body);
      if ("error" in parsed) return error(reply, parsed.error, 400);
      const order = await createIssuedOrder(parsed.data);
      await logAudit({
        request,
        authData: request.authData,
        action: "create",
        entityType: "issued_order",
        entityId: order.id,
        description: `Vytvořena vydaná objednávka ${order.po_number}`,
      });
      return success(
        reply,
        { id: order.id, po_number: order.po_number },
        201,
        "Objednávka byla vytvořena",
      );
    },
  );

  // PUT /api/admin/issued-orders/:id
  fastify.put<{ Params: { id: string } }>(
    "/:id",
    { preHandler: requirePermission("orders.edit") },
    async (request, reply) => {
      const id = parseId(request.params.id, reply);
      if (id === null) return;
      const parsed = parseBody(UpdateIssuedOrderSchema, request.body);
      if ("error" in parsed) return error(reply, parsed.error, 400);
      const result = await updateIssuedOrder(id, parsed.data);
      if ("error" in result) {
        if (result.error === "not_found")
          return error(reply, "Objednávka nenalezena", 404);
        if (result.error === "invalid_transition")
          return error(
            reply,
            `Neplatný přechod stavu z "${result.currentStatus}" na "${result.newStatus}"`,
            400,
          );
        return error(reply, "Neznámá chyba", 500);
      }
      await logAudit({
        request,
        authData: request.authData,
        action: "update",
        entityType: "issued_order",
        entityId: id,
        description: `Upravena vydaná objednávka ${result.po_number}`,
      });
      return success(reply, { id }, 200, "Objednávka byla aktualizována");
    },
  );

  // DELETE /api/admin/issued-orders/:id
  fastify.delete<{ Params: { id: string } }>(
    "/:id",
    { preHandler: requirePermission("orders.delete") },
    async (request, reply) => {
      const id = parseId(request.params.id, reply);
      if (id === null) return;
      const existing = await deleteIssuedOrder(id);
      if (!existing) return error(reply, "Objednávka nenalezena", 404);
      await logAudit({
        request,
        authData: request.authData,
        action: "delete",
        entityType: "issued_order",
        entityId: id,
        description: `Smazána vydaná objednávka ${existing.po_number}`,
      });
      return success(reply, null, 200, "Objednávka smazána");
    },
  );
}
