import dayjs from 'dayjs';
import { Router } from 'express';
import Joi from 'joi';

import { getUrl } from '@blocklet/sdk';
import { joinURL } from 'ufo';
import { authenticate } from '../libs/security';
import { formatToShortUrl } from '../libs/url';
import { CheckoutSession } from '../store/models';
import logger from '../libs/logger';

const loginAuth = authenticate<CheckoutSession>({ component: false, ensureLogin: true, mine: true });

const router = Router();

const shortUrlSchema = Joi.object({
  url: Joi.string().uri().required(),
  timeoutMin: Joi.number().optional(),
  maxVisits: Joi.number().optional(),
}).unknown(true);

router.get('/short-url', loginAuth, async (req, res) => {
  const { error } = shortUrlSchema.validate(req.query);
  if (error) {
    return res.status(400).json({ error: 'Invalid parameters', message: error.message });
  }
  const { url, timeoutMin = 60, maxVisits = 5 } = req.query;
  const timeoutMinNumber = Number(timeoutMin);
  const validUntil = dayjs()
    .add(timeoutMinNumber > 60 ? 60 : timeoutMinNumber, 'minutes')
    .format('YYYY-MM-DDTHH:mm:ss+00:00');

  const shortUrl = await formatToShortUrl({ url: url as string, validUntil, maxVisits: Number(maxVisits) });

  return res.json({ url: shortUrl });
});

router.get('/short-connect-url', async (req, res) => {
  const { error } = shortUrlSchema.validate(req.query);
  if (error) {
    return res.status(400).json({ error: 'Invalid parameters', message: error.message });
  }

  const { url, timeoutMin = 60, maxVisits = 5 } = req.query;
  const serverUrl = getUrl();

  const allowedEndpoint = joinURL(new URL(serverUrl).origin, '.well-known/service/gen-simple-access-key');

  if (!url?.toString().startsWith(allowedEndpoint)) {
    logger.error('Client try to generate short connect url from invalid service', { url });
    return res
      .status(400)
      .json({ error: 'Just support generate short connect url from gen-simple-access-key service' });
  }

  const timeoutMinNumber = Number(timeoutMin);
  const validUntil = dayjs()
    .add(timeoutMinNumber > 60 ? 60 : timeoutMinNumber, 'minutes')
    .format('YYYY-MM-DDTHH:mm:ss+00:00');

  const shortUrl = await formatToShortUrl({ url: url as string, validUntil, maxVisits: Number(maxVisits) });
  return res.json({ url: shortUrl });
});

export default router;
