import Controller from "swaf/Controller";
import {NextFunction, Request, Response} from "express";
import URLRedirect from "../models/URLRedirect";
import {RequireAuthMiddleware} from "swaf/auth/AuthComponent";
import generateSlug from "../SlugGenerator";
import config from "config";
import AuthToken from "../models/AuthToken";

export default class URLRedirectController extends Controller {
    routes(): void {
        this.get('/url/shrink', this.getURLShrinker, 'url-shrinker', RequireAuthMiddleware);
        this.get('/url/shrink/script', this.downloadLinuxScript, 'url-linux-script');
        this.post('/url/shrink', this.addURLFrontend, 'shrink-url', RequireAuthMiddleware);
        this.get('/urls/:page([0-9]+)?', this.getURLRedirectManager, 'url-manager', RequireAuthMiddleware);
    }

    protected async getURLShrinker(req: Request, res: Response): Promise<void> {
        const user = req.as(RequireAuthMiddleware).getUser();
        const allowedDomains = config.get<string[]>('allowed_url_domains');
        res.render('url-shrinker', {
            auth_tokens: await AuthToken.select().where('user_id', user.id).get(),
            allowed_domains: allowedDomains,
            default_domain: allowedDomains[config.get<number>('default_url_domain_for_urls')],
        });
    }

    protected async downloadLinuxScript(req: Request, res: Response): Promise<void> {
        res.download('assets/files/shrink_url.sh', 'shrink_url.sh');
    }

    protected async getURLRedirectManager(req: Request, res: Response): Promise<void> {
        const user = req.as(RequireAuthMiddleware).getUser();
        res.render('url-manager', {
            urls: await URLRedirect.paginateForUser(req, 100, user.getOrFail('id')),
        });
    }

    protected async addURLFrontend(req: Request, res: Response, next: NextFunction): Promise<void> {
        req.body.type = 'url';
        await URLRedirectController.addURL(req, res, next, req.body.autogen_url === undefined && req.body.slug ? req.body.slug : await generateSlug(10));
    }

    public static async addURL(req: Request, res: Response, next: NextFunction, slug?: string): Promise<void> {
        if (req.body.type !== 'url') return next();

        const user = req.as(RequireAuthMiddleware).getUser();
        slug = slug || req.params.slug || req.body.slug || await generateSlug(10);
        const urlRedirect = URLRedirect.create({
            user_id: user.id,
            slug: slug,
            target_url: req.body.target_url,
        });

        await urlRedirect.save();

        const domain = req.body.url_domain || config.get<string[]>('allowed_url_domains')[config.get<number>('default_url_domain_for_urls')];
        res.format({
            json: () => res.json({
                url: urlRedirect.getURL(domain),
            }),
            text: () => res.send(urlRedirect.getURL(domain)),
            html: () => {
                req.flash('success', 'URL shrunk successfully!');
                req.flash('url', urlRedirect.getURL(domain));
                res.redirectBack('/');
            },
        });
    }
}