import axios, {AxiosResponse} from "axios";
import {configs} from "@/lib/configs";

export default class System{
    static verifyInput(input: string): boolean {
        let pattern: RegExp = new RegExp('(<.*?>)|(&.*?;)|({.*?})', 'gmi');
        return pattern.test(input);
    }

    public static timeStampInSeconds(): number {
        const date: number = new Date().getTime();
        return Math.floor(date / 1000);
    }

    public static formatHTMLContent(htmlContent: string): string {
        return htmlContent
            .replace(/<h1>/g, '<h1 style="color: #FFFFFF; text-indent: 5px; font-size: 28px; font-weight: bold; text-align: left; margin-vertical: 10px;">')
            .replace(/<p>/g, '<p style="color: #d0d0d0; text-indent: 30px; font-size: 16px; line-height: 22px; margin-vertical: 5px;">')
            .replace(/<blockquote>/g, '<blockquote style="border-left-width: 4px; border-left-color: #ccc; padding-left: 10px; font-style: italic; color: #555;">');
    }
    
    public static textContentToHtml(content: string): string {
        const paragraphs: string[] = content
            .split(/\n+/)
            .map((paragraph: string) => paragraph.trim())
            .filter((paragraph: string) => paragraph.length > 0);
        
        return paragraphs
            .map((paragraph: string) => `<p>${paragraph}</p>`)
            .join('');
    }
    
    public static async authGetQueryToServer<T>(url: string, auth: string, lang: string = "fr", params: Record<string, any> = {}): Promise<T> {
        try {
            const response: AxiosResponse<T> = await axios({
                method: 'GET',
                headers: {
                    'Authorization': `Bearer ${auth}`
                },
                params: {
                    lang: lang,
                    plateforme: window.electron.platform,
                    ...params
                },
                url: configs.apiUrl + url,
            })
            return response.data;
        } catch (e: unknown) {
            if (axios.isAxiosError(e)) {
                const serverMessage: string = e.response?.data?.message || e.response?.data || e.message;
                throw new Error(serverMessage as string);
            } else if (e instanceof Error) {
                throw new Error(e.message);
            } else {
                throw new Error('An unexpected error occurred');
            }
        }
    }
    
    public static setCookie(name: string, value: string, days: number): void {
        const date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        const expires = `expires=${date.toUTCString()}`;
        let domain: string = '';
        if (!/localhost|127\.0\.0\.1/.test(window.location.hostname)) {
            domain = `domain=${window.location.hostname};`;
        }
        const secure = 'Secure;';
        const sameSite = 'SameSite=Strict;';
        document.cookie = `${name}=${value}; ${expires}; ${domain} path=/; ${secure} ${sameSite}`;
    }
    
    public static async authPutToServer<T>(url: string, data: {}, auth: string, lang: string = "fr"): Promise<T> {
        try {
            const response: AxiosResponse<T> = await axios({
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${auth}`
                },
                params: {
                    lang: lang,
                    plateforme: window.electron.platform,
                },
                url: configs.apiUrl + url,
                data: data
            })
            return response.data;
        } catch (e: unknown) {
            if (axios.isAxiosError(e)) {
                const serverMessage: string = e.response?.data?.message || e.response?.data || e.message;
                throw new Error(serverMessage as string);
            } else if (e instanceof Error) {
                throw new Error(e.message);
            } else {
                throw new Error('An unexpected error occurred');
            }
        }
    }
    
    public static async authPatchToServer<T>(url: string, data: {}, auth: string, lang: string = "fr"): Promise<T> {
        try {
            const response: AxiosResponse<T> = await axios({
                method: 'patch',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${auth}`
                },
                params: {
                    lang: lang,
                    plateforme: window.electron.platform,
                },
                url: configs.apiUrl + url,
                data: data
            })
            return response.data;
        } catch (e: unknown) {
            if (axios.isAxiosError(e)) {
                const serverMessage: string = e.response?.data?.message || e.response?.data || e.message;
                throw new Error(serverMessage as string);
            } else if (e instanceof Error) {
                throw new Error(e.message);
            } else {
                throw new Error('An unexpected error occurred');
            }
        }
    }
    
    public static async postToServer<T>(url: string, data: {}, lang: string = "fr"): Promise<T> {
        try {
            const response: AxiosResponse<T> = await axios({
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                url: configs.apiUrl + url,
                params: {
                    lang: lang,
                    plateforme: window.electron.platform,
                },
                data: data
            })
            return response.data;
        } catch (e: unknown) {
            if (axios.isAxiosError(e)) {
                const serverMessage: string = e.response?.data?.message || e.response?.data || e.message;
                throw new Error(serverMessage as string);
            } else if (e instanceof Error) {
                throw new Error(e.message);
            } else {
                throw new Error('An unexpected error occurred');
            }
        }
    }

    public static async authPostToServer<T>(url: string, data: {}, auth: string, lang: string = "fr"): Promise<T> {
        try {
            const response: AxiosResponse<T> = await axios({
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${auth}`
                },
                url: configs.apiUrl + url,
                params: {
                    lang: lang,
                    plateforme: window.electron.platform,
                },
                data: data
            })
            return response.data;
        } catch (e: unknown) {
            if (axios.isAxiosError(e)) {
                const serverMessage: string = e.response?.data?.message || e.response?.data || e.message;
                throw new Error(serverMessage as string);
            } else if (e instanceof Error) {
                throw new Error(e.message);
            } else {
                throw new Error('An unexpected error occurred');
            }
        }
    }

    static htmlToText(html: string) {
        return html
            .replace(/<br\s*\/?>/gi, '\n')
            .replace(/<\/?(p|h[1-6]|div)(\s+[^>]*)?>/gi, '\n')
            .replace(/<\/?[^>]+(>|$)/g, '')
            .replace(/(\n\s*){2,}/g, '\n\n')
            .replace(/^\s+|\s+$|(?<=\s)\s+/g, '')
            .trim();
    }

    public static getCookie(name: string): string | null {
        const nameEQ = `${name}=`;
        const allCookies: string[] = document.cookie.split(';');
        for (let i: number = 0; i < allCookies.length; i++) {
            let cookie: string = allCookies[i];
            while (cookie.charAt(0) === ' ') cookie = cookie.substring(1, cookie.length);
            if (cookie.indexOf(nameEQ) === 0) return cookie.substring(nameEQ.length, cookie.length);
        }
        return null;
    }
    
    public static removeCookie(name: string): void {
        let domain: string = '';
        if (!/localhost|127\.0\.0\.1/.test(window.location.hostname)) {
            domain = `domain=${window.location.hostname};`;
        }
        const secure = 'Secure;';
        const sameSite = 'SameSite=Strict;';
        document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; ${domain} path=/; ${secure} ${sameSite}`;
    }
    
    public static async authUploadFileToServer<T>(url: string, file: File, auth: string, lang: string = "fr"): Promise<T> {
        try {
            const formData: FormData = new FormData();
            formData.append('file', file);
            formData.append('lang', lang);
            formData.append('plateforme', window.electron.platform);

            const response: AxiosResponse<T> = await axios({
                method: 'POST',
                headers: {
                    'Authorization': `Bearer ${auth}`,
                },
                url: configs.apiUrl + url,
                params: {
                    lang: lang,
                    plateforme: window.electron.platform,
                },
                data: formData,
            });
            return response.data;
        } catch (e: unknown) {
            if (axios.isAxiosError(e)) {
                const serverMessage: string = e.response?.data?.message || e.response?.data || e.message;
                throw new Error(serverMessage as string);
            } else if (e instanceof Error) {
                throw new Error(e.message);
            } else {
                throw new Error('An unexpected error occurred');
            }
        }
    }

    public static async authDeleteToServer<T>(url: string, data: {}, auth: string, lang: string = "fr"): Promise<T> {
        try {
            const response: AxiosResponse<T> = await axios({
                method: 'DELETE',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${auth}`
                },
                url: configs.apiUrl + url,
                params: {
                    lang: lang,
                    plateforme: window.electron.platform,
                },
                data: data
            })
            return response.data;
        } catch (e: unknown) {
            if (axios.isAxiosError(e)) {
                const serverMessage: string = e.response?.data?.message || e.response?.data || e.message;
                throw new Error(serverMessage as string);
            } else if (e instanceof Error) {
                throw new Error(e.message);
            } else {
                throw new Error('An unexpected error occurred');
            }
        }
    }
}
