import {FastifyReply, FastifyRequest} from 'fastify';
import {processM3U8Content, proxyRequest, streamToReadable} from './proxy.service';

interface ProxyQuerystring {
    url: string;
    referer?: string;
    origin?: string;
    userAgent?: string;
}

type ProxyRequest = FastifyRequest<{
    Querystring: ProxyQuerystring
}>;

export async function handleProxy(req: ProxyRequest, reply: FastifyReply) {
    const { url, referer, origin, userAgent } = req.query;

    if (!url) {
        return reply.code(400).send({ error: "No URL provided" });
    }

    try {
        const rangeHeader = req.headers.range;

        const { response, contentType, isM3U8, contentLength } = await proxyRequest(url, {
            referer,
            origin,
            userAgent
        }, rangeHeader);


        reply.header('Access-Control-Allow-Origin', '*');
        reply.header('Access-Control-Allow-Methods', 'GET, OPTIONS');
        reply.header('Access-Control-Allow-Headers', 'Content-Type, Range');
        reply.header('Access-Control-Expose-Headers', 'Content-Length, Content-Range, Accept-Ranges');

        if (isM3U8) {
            reply.header('Content-Type', 'application/vnd.apple.mpegurl');

            const text = await response.text();
            const baseUrl = new URL(response.url);

            const processedContent = processM3U8Content(text, baseUrl, {
                referer,
                origin,
                userAgent
            });

            return reply.send(processedContent);
        }

        const isSubtitle = url.includes('.vtt') || url.includes('.srt') || url.includes('.ass') ||
            contentType?.includes('text/vtt') || contentType?.includes('text/srt');

        if (isSubtitle) {
            const text = await response.text();

            let mimeType = 'text/vtt';
            if (url.includes('.srt') || contentType?.includes('srt')) {
                mimeType = 'text/plain';
            } else if (url.includes('.ass')) {
                mimeType = 'text/plain';
            }

            reply.header('Content-Type', mimeType);
            reply.header('Cache-Control', 'public, max-age=3600');
            return reply.send(text);
        }

        if (contentType) {
            reply.header('Content-Type', contentType);
        }

        if (response.status === 206) {
            const contentRange = response.headers.get('content-range');
            if (contentRange) {
                reply.header('Content-Range', contentRange);
            }
            reply.code(206);
        }

        if (contentLength) {
            reply.header('Content-Length', contentLength);
        }

        if (contentType?.startsWith('image/') || contentType?.startsWith('video/')) {
            reply.header('Cache-Control', 'public, max-age=31536000, immutable');
        }

        reply.header('Accept-Ranges', 'bytes');

        return reply.send(streamToReadable(response.body!));

    } catch (err) {
        req.server.log.error(err);
        console.error('=== PROXY ERROR ===');
        console.error('URL:', url);
        console.error('Error:', err);
        console.error('===================');

        if (!reply.sent) {
            return reply.code(500).send({
                error: "Internal Server Error",
                details: err instanceof Error ? err.message : String(err)
            });
        }
    }
}

export async function handleProxyOptions(req: FastifyRequest, reply: FastifyReply) {
    reply.header('Access-Control-Allow-Origin', '*');
    reply.header('Access-Control-Allow-Methods', 'GET, OPTIONS');
    reply.header('Access-Control-Allow-Headers', 'Content-Type, Range');
    return reply.code(204).send();
}