import { Router } from "express";
import { SubscriptionStatus } from "@prisma/client";
import { prisma } from "../../db/prisma.js";
import { requireAuth, type AuthenticatedRequest } from "../../middleware/auth.js";
import { signalListSchema } from "./signals.schemas.js";
import { listActiveSignalCountsByBot, listSignals } from "./signals.service.js";

export const signalsRouter = Router();

signalsRouter.use(requireAuth);

function withCreatedAtAsSignalTime<T extends { signalTime: Date; createdAt: Date }>(signal: T) {
  return {
    ...signal,
    signalTime: signal.createdAt
  };
}

function activeSubscriptionWhere(userId: string, botKey: string) {
  const now = new Date();

  return {
    userId,
    status: SubscriptionStatus.active,
    startsAt: {
      lte: now
    },
    OR: [
      {
        expiresAt: null
      },
      {
        expiresAt: {
          gte: now
        }
      }
    ],
    bot: {
      key: botKey
    }
  };
}

signalsRouter.get("/", async (req: AuthenticatedRequest, res, next) => {
  try {
    const filters = signalListSchema.parse(req.query);
    const signals = await listSignals(filters, {
      userId: req.user?.id,
      role: req.user?.role
    });
    res.json(signals);
  } catch (error) {
    next(error);
  }
});

signalsRouter.get("/active-counts", async (req: AuthenticatedRequest, res, next) => {
  try {
    const result = await listActiveSignalCountsByBot({
      userId: req.user?.id,
      role: req.user?.role
    });
    res.json(result);
  } catch (error) {
    next(error);
  }
});

signalsRouter.get("/:id", async (req: AuthenticatedRequest, res) => {
  const signal = await prisma.signal.findUnique({
    where: { id: String(req.params.id) },
    include: { settlement: true, notifications: true }
  });

  if (!signal) {
    return res.status(404).json({ message: "Сигнал не найден" });
  }

  if (req.user?.role !== "admin" && signal.sourceType !== "manual") {
    const payload = signal.rawPayload && typeof signal.rawPayload === "object"
      ? (signal.rawPayload as Record<string, unknown>)
      : null;
    const botKey = payload?.botKey ? String(payload.botKey) : "";

    if (!botKey) {
      return res.status(403).json({ message: "Нет доступа к сигналу" });
    }

    const access = await prisma.userBotAccess.findFirst({
      where: activeSubscriptionWhere(req.user!.id, botKey)
    });

    if (!access) {
      return res.status(403).json({ message: "Нет доступа к сигналу" });
    }
  }

  return res.json(withCreatedAtAsSignalTime(signal));
});
