import React, {useContext} from 'react';
import useLoading from "../../../hooks/useLoading";
import {toastError, toastSuccess, toastWarn} from "../../../services/toaster";
import {
    deleteFile, deleteFileEmergency,
    downloadFile, downloadFileEmergency,
    editFile,
    moveFile,
    replaceFile,
    uploadFile, uploadFileEmergency
} from "../../../API/hr_support";
import useRole from "../../../hooks/useRole";
import {
    deleteFileRescom,
    downloadFileRescom,
    editFileRescom, moveFileRescom,
    replaceFileRescom,
    uploadFileRescom
} from "../../../API/rescom";
import AuthContext from "../../../context/auth-context";

function blobToBase64(blob: any) {
    return new Promise((resolve, _) => {
        const reader = new FileReader();
        reader.onloadend = () => resolve(reader.result);
        reader.readAsDataURL(blob);
    });
}

const UseFile = (updateFiles?: () => void) => {
    const activeRole = useRole();
    const {currentUser} = useContext(AuthContext);
    const workRelation = currentUser?.work_relation_id;

    const emergencyRoles = [
        'hr_manager',
        'scientific_supervisor',
        'project_manager',
        'supervisor_elke',
    ];
    const permanentRoles = [
        'ddoy_hr_department_users',
        'permanent_personnel_manager',
        'ddoy_supervisor_directorate',
    ];

    const [loading, setLoading] = useLoading(true);

    // ─── Shared: pick the right download API based on role/project ────────────
    const selectDownloadMethod = (project_code: string, role: string) => {
        if (project_code) return downloadFileRescom;
        if (role === 'dua_user') {
            if (workRelation === 1) return downloadFile;
            if (workRelation === 2) return downloadFileEmergency;
        }
        if (permanentRoles.includes(role)) return downloadFile;
        if (emergencyRoles.includes(role)) return downloadFileEmergency;
        return downloadFileRescom; // fallback
    };

    // ─── Returns the raw Blob for a single file (used for ZIP building) ───────
    const getFileBlob = async (
        filepath: string,
        project_code: string,
        role: string
    ): Promise<Blob> => {
        const downloadMethod = selectDownloadMethod(project_code, role);
        const res = await downloadMethod(filepath, project_code, role);
        return res.data as Blob;
    };

    // ─── Single-file download (triggers browser save) ─────────────────────────
    const handleFileDownload = async (
        filepath: string,
        name: string = 'file',
        project_code: string,
        role: string
    ) => {
        try {
            setLoading(true);
            const blob = await getFileBlob(filepath, project_code, role);
            const myLink = document.createElement('a');
            myLink.href = window.URL.createObjectURL(blob);
            myLink.download = name;
            myLink.click();
        } catch (e: any) {
            if (e.response?.data?.message) toastWarn(e.response.data.message);
            else toastError('Κάτι πήγε στραβά');
        } finally {
            setLoading(false);
        }
    };

    const handleFileReplace = async (filepath: string, project_code: string, activeRole: string) => {
        const input = document.createElement('input');
        input.type = 'file';
        input.click();

        input.onchange = async (e: any) => {
            const file = e.target.files[0];

            if (file && file.size > 82943040) {
                toastWarn('Πολύ μεγάλο μέγεθος αρχείου.');
                return;
            }

            const buildFormData = () => {
                const formData = new FormData();
                formData.append('file[]', file);
                formData.append('filepath[]', filepath);
                if (project_code) formData.append('project_code', project_code);
                return formData;
            };

            const selectReplaceMethod = () => {
                if (project_code) return replaceFileRescom;
                if (activeRole === 'dua_user') {
                    if (workRelation === 1) return replaceFile;
                }
                if (permanentRoles.includes(activeRole)) return replaceFile;
                return replaceFileRescom; // fallback
            };

            const formDataObject = buildFormData();
            const replaceMethod = selectReplaceMethod();

            try {
                setLoading(true);
                await replaceMethod(formDataObject);
                toastSuccess('Το αρχείο ανέβηκε με επιτυχία');
                if (updateFiles) await updateFiles();
            } catch (e: any) {
                if (e.response?.data?.message) toastWarn(e.response.data.message);
                else toastError('Κάτι πήγε στραβά');
            } finally {
                setLoading(false);
            }
        };
    };

    const handleFileUpload = async (data: Record<string, any>) => {
        const {
            file,
            files,
            file_category_id,
            subfolder_id,
            subfolder_id_emergency,
            subject,
            protocol_number,
            user_id,
            contract_code,
            project_code,
            role,
        } = data;

        const filesToUpload: File[] = [
            ...(Array.isArray(file) ? file : file ? [file] : []),
            ...(Array.isArray(files) ? files : []),
        ];

        if (filesToUpload.some(f => f.size > 41943040)) {
            toastWarn('Πολύ μεγάλο μέγεθος αρχείου.');
            return false;
        }

        const buildFormData = (filesArray: File[]) => {
            const formData = new FormData();
            file_category_id && formData.append('file_category_id', file_category_id.toString());
            subfolder_id && formData.append('subfolder_id', subfolder_id.toString());
            subfolder_id_emergency && formData.append('subfolder_id_emergency', subfolder_id_emergency.toString());
            subject && formData.append('subject', subject);
            protocol_number && formData.append('protocol_number', protocol_number);
            user_id && formData.append('user_id', user_id.toString());
            role && formData.append('active_role', role ?? '');
            contract_code && formData.append('contract_code[]', contract_code);
            project_code && formData.append('project_code', project_code);
            filesArray.forEach(f => formData.append('file[]', f));
            return formData;
        };

        const selectUploadMethod = () => {
            if (project_code) return uploadFileRescom;
            if (activeRole === 'dua_user') {
                if (workRelation === 1) return uploadFile;
                if (workRelation === 2) return uploadFileEmergency;
            }
            if (permanentRoles.includes(activeRole)) return uploadFile;
            if (emergencyRoles.includes(activeRole)) return uploadFileEmergency;
            return uploadFileRescom;
        };

        const uploadMethod = selectUploadMethod();

        try {
            setLoading(true);
            await uploadMethod(buildFormData(filesToUpload));
            toastSuccess('Το/Τα αρχείο/α ανέβηκε/αν με επιτυχία.');
        } catch (e: any) {
            if (e.response?.data?.message) toastWarn(e.response.data.message);
            else toastError('Κάτι πήγε στραβά.');
            setLoading(false);
            return false;
        }

        setLoading(false);
        updateFiles && await updateFiles();
        return true;
    };

    const handleFileDelete = async (
        uuid: string,
        filepath: string,
        project_code: string,
        activeRole: string,
        fileCategoryId?: string,
        hashId?: string
    ) => {
        setLoading(true);
        try {
            if (project_code) {
                await deleteFileRescom(uuid, filepath, project_code, activeRole);
            } else if (activeRole === 'dua_user') {
                if (workRelation === 1) {
                    await deleteFile(uuid, filepath);
                } else if (workRelation === 2) {
                    await deleteFileEmergency(activeRole, fileCategoryId!, hashId!, uuid, filepath);
                }
            } else if (permanentRoles.includes(activeRole)) {
                await deleteFile(uuid, filepath);
            } else if (emergencyRoles.includes(activeRole)) {
                await deleteFileEmergency(activeRole, fileCategoryId!, hashId!, uuid, filepath);
            } else {
                await deleteFileRescom(uuid, filepath, project_code, activeRole);
            }

            toastSuccess('Το αρχείο διαγράφηκε με επιτυχία.');
            updateFiles && updateFiles();
        } catch (e: any) {
            if (e.response?.data?.message) toastWarn(e.response.data.message);
            else toastError('Κάτι πήγε στραβά.');
        } finally {
            setLoading(false);
        }
    };

    const handleFileEdit = async (
        filepath: string,
        subject: string,
        protocol_number: string,
        project_code: string,
        activeRole: string
    ) => {
        const selectEditMethod = () => {
            if (project_code) return editFileRescom;
            if (activeRole === 'dua_user') {
                if (workRelation === 1) return editFile;
            }
            if (permanentRoles.includes(activeRole)) return editFile;
            return editFileRescom; // fallback
        };

        setLoading(true);
        try {
            const editMethod = selectEditMethod();
            await editMethod(filepath, subject, protocol_number, project_code, activeRole);
            toastSuccess('Το αρχείο επεξεργάστηκε με επιτυχία.');
            updateFiles && updateFiles();
            return true;
        } catch (e: any) {
            if (e.response?.data?.message) toastWarn(e.response.data.message);
            else toastError('Κάτι πήγε στραβά.');
            return false;
        } finally {
            setLoading(false);
        }
    };

    const handleFileMove = async (
        filepath: string,
        subfolder_id: number,
        subfolder_id_emergency: number | null,
        withAttachments = false,
        project_code: string,
        activeRole: string
    ) => {
        const selectMoveMethod = () => {
            if (project_code) return moveFileRescom;
            if (activeRole === 'dua_user') {
                if (workRelation === 1) return moveFile;
            }
            if (permanentRoles.includes(activeRole)) return moveFile;
            return moveFileRescom; // fallback
        };

        setLoading(true);
        try {
            const moveMethod = selectMoveMethod();
            await moveMethod(filepath, subfolder_id, project_code, activeRole);
            toastSuccess('Το αρχείο μετακινήθηκε σε άλλο υποφάκελο.');
            updateFiles && updateFiles();
        } catch (e: any) {
            if (e.response?.data?.message) toastWarn(e.response.data.message);
            else toastError('Κάτι πήγε στραβά.');
        } finally {
            setLoading(false);
        }
    };

    return {
        getFileBlob,
        handleFileReplace,
        handleFileDownload,
        handleFileUpload,
        handleFileDelete,
        handleFileEdit,
        handleFileMove,
    };
};

export default UseFile;
