"use strict";

const jwt = require("jsonwebtoken");
const config = require("../config");
const signalService = require("../services/signalService");
const signalEvents = require("../events/signalEvents");
const ApiResponse = require("../utils/apiResponse");
const { asyncHandler } = require("../middleware/errorHandler");

exports.getProviders = asyncHandler(async (req, res) => {
  const data = await signalService.getProviderDirectory(req.user.id, {
    page: Number(req.query.page || 1),
    limit: Number(req.query.limit || 24),
  });
  ApiResponse.success(res, data);
});

exports.getMySubscriptions = asyncHandler(async (req, res) => {
  const data = await signalService.getMySubscriptions(req.user.id, {
    page: Number(req.query.page || 1),
    limit: Number(req.query.limit || 100),
  });
  ApiResponse.success(res, data);
});

exports.getMyFeed = asyncHandler(async (req, res) => {
  const data = await signalService.getMyFeed(req.user.id, {
    page: Number(req.query.page || 1),
    limit: Number(req.query.limit || 50),
  });
  ApiResponse.success(res, data);
});

exports.getMyHistory = asyncHandler(async (req, res) => {
  const data = await signalService.getMyFeed(req.user.id, {
    page: Number(req.query.page || 1),
    limit: Number(req.query.limit || 50),
    historyOnly: true,
  });
  ApiResponse.success(res, data);
});

exports.getMyStats = asyncHandler(async (req, res) => {
  const data = await signalService.getUserStats(req.user.id);
  ApiResponse.success(res, data);
});

exports.subscribe = asyncHandler(async (req, res) => {
  const data = await signalService.subscribe(req.user.id, Number(req.params.providerId));
  ApiResponse.success(res, data, "Subscribed successfully");
});

exports.unsubscribe = asyncHandler(async (req, res) => {
  const data = await signalService.unsubscribe(req.user.id, Number(req.params.providerId));
  ApiResponse.success(res, data, "Unsubscribed successfully");
});

exports.buySignal = asyncHandler(async (req, res) => {
  const data = await signalService.buySignal(req.user.id, Number(req.params.signalId));
  ApiResponse.success(res, data, "Signal bought successfully");
});

exports.copySignal = asyncHandler(async (req, res) => {
  const data = await signalService.buySignal(req.user.id, Number(req.params.signalId));
  ApiResponse.success(res, data, "Signal copied successfully");
});

exports.stopAll = asyncHandler(async (req, res) => {
  const data = await signalService.stopAll(req.user.id);
  ApiResponse.success(res, data, "All active subscriptions paused");
});

exports.getProviderSignals = asyncHandler(async (req, res) => {
  const data = await signalService.getMyProviderSignals(req.user.id, {
    page: Number(req.query.page || 1),
    limit: Number(req.query.limit || 50),
    status: req.query.status || undefined,
  });
  ApiResponse.success(res, data);
});

exports.createSignal = asyncHandler(async (req, res) => {
  const data = await signalService.createSignal(req.user.id, req.body);
  ApiResponse.success(res, data, "Signal created successfully");
});

exports.updateSignal = asyncHandler(async (req, res) => {
  const data = await signalService.updateSignal(req.user.id, Number(req.params.signalId), req.body);
  ApiResponse.success(res, data, "Signal updated successfully");
});

exports.updateSignalPrice = asyncHandler(async (req, res) => {
  const data = await signalService.updateSignalPrice(
    req.user.id,
    Number(req.params.signalId),
    Number(req.body.currentPrice)
  );
  ApiResponse.success(res, data, "Signal price updated successfully");
});

exports.closeSignal = asyncHandler(async (req, res) => {
  const data = await signalService.closeSignal(req.user.id, Number(req.params.signalId), req.body);
  ApiResponse.success(res, data, "Signal closed successfully");
});

exports.cancelSignal = asyncHandler(async (req, res) => {
  const data = await signalService.cancelSignal(req.user.id, Number(req.params.signalId));
  ApiResponse.success(res, data, "Signal cancelled successfully");
});

exports.placeSignal = asyncHandler(async (req, res) => {
  const data = await signalService.placeSignal(req.user.id, Number(req.params.signalId));
  ApiResponse.success(res, data, "Signal cancelled successfully");
});

exports.stream = (req, res) => {
  const token =
    req.query.token ||
    (req.headers.authorization || "").replace(/^Bearer\s+/i, "");

  if (!token) {
    return res.status(401).json({
      success: false,
      message: "Unauthorized",
    });
  }

  try {
    const decoded = jwt.verify(token, config.jwt.secret);
    const userId = decoded.id;

    res.setHeader("Content-Type", "text/event-stream");
    res.setHeader("Cache-Control", "no-cache, no-transform");
    res.setHeader("Connection", "keep-alive");
    if (typeof res.flushHeaders === "function") {
      res.flushHeaders();
    }

    const send = (event) => {
      res.write(`data: ${JSON.stringify(event)}\n\n`);
    };

    send({
      type: "connected",
      payload: { ok: true },
      timestamp: new Date().toISOString(),
    });

    const heartbeat = setInterval(() => {
      send({
        type: "ping",
        payload: {},
        timestamp: new Date().toISOString(),
      });
    }, 25000);

    const unsubscribe = signalEvents.subscribe(String(userId), send);

    req.on("close", () => {
      clearInterval(heartbeat);
      unsubscribe();
      res.end();
    });
  } catch (error) {
    return res.status(401).json({
      success: false,
      message: "Invalid token",
    });
  }
};