import { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { Form, Formik } from "formik";
import { CometChat } from "@cometchat/chat-sdk-javascript";
import Modal from "@/Component/Common/Modal";
import ConfirmationModal from "@/Component/Common/Modal/ConfirmationModal";
import { AppStore } from "@/lib/store";
import QuickApplyForm from "./QuickApplyForm";
import BorderButton from "@/Component/Common/Forms/BorderButton";
import PrimaryButton from "@/Component/Common/Forms/PrimaryButton";
import { RequiredField, RequiredIntegerWithDecimalField, YupObject } from "@/Utils/ValidationSchema";
import usePost from "@/Utils/Hooks/usePost";
import { CommonS3BucketUploadAPI, CommonUploadAPI, JobEasyApplyAPI, JobEditPriceAPI } from "@/Utils/APIRequest/Endpoints";
import { InfoCircleSVG, LoaderSVG } from "@/Component/Common/SVGs/CommonSVG";
import AppliedSuccessfully from "./AppliedSuccessfully";
import moment from "moment";
import { getUserDetails } from "@/lib/Features/UserDetails/userDetails";
import { formatNumber } from "@/Utils/Other/FormateNumbers";
import ImageWithFallback from "@/Component/Common/ImageWithFallback";
import { CustomToast } from "@/Utils/CustomToast";
import { RiAttachment2, RiDeleteBin2Line, RiLoader2Fill } from "react-icons/ri";
import { formatNumberWithCommas } from "@/Utils/Other/FormatNumberWithCommas";
import * as Yup from "yup";
import { useQuery } from "@tanstack/react-query";
import CustomFetch from "@/Utils/APIRequest/AxiosInstance";

const QuickApply = (props) => {
    const { modal, setModal, refetch, mainListRefetch, setOpenSideModal, setActiveTab, translations, setParams, params, composerRef, onCloseSidebar } = props;
    const userDetails: any = useSelector((state: AppStore) => state.userDetailSlice?.userDetails);
    const [isApplied, setIsApplied] = useState(false);
    const [formValues, setFormValues] = useState<any>(null);
    const [uploadedFiles, setUploadedFiles] = useState<any>([]);
    const [fileType, setFileType] = useState(false);
    const dispatch = useDispatch();
    const [mediaType, setMediaType] = useState('');
    const [thumbnail, setThumbnail] = useState('');
    const [uploadS3Loader, setUploadS3Loader] = useState(false);
    const [preSignedUrl, setPreSignedUrl] = useState(false);
    const [newFileName, setNewFileName] = useState('');
    const [selectedFile, setSelectedFile] = useState<File | null>(null);
    const [reviseConfirmOpen, setReviseConfirmOpen] = useState(false);
    const [pendingValues, setPendingValues] = useState<any>(null);
    const [fileParams, setFileParams] = useState({
        root: "files",
        type: "campaign",
        fileName: "",
        contentType: "",
    });

    const afterQuoteStatus = {
        "drafting_deliverables": true,
        "draft_available": true,
        "posting_deliverables": true,
        "completion_request": true
    }

    const handleContactNow = async (GUIDValue) => {

        let GUID: string = String(GUIDValue);
        let groupName: string = userDetails?.display_name;
        let groupType: string = CometChat.GROUP_TYPE.PUBLIC;
        let password: string = "";
        let groupIcon: string = userDetails?.image !== '' ? userDetails?.image : "https://d1i31jsql1ktvl.cloudfront.net/images/profile/placeholder.jpg";
        let groupDescription: string = modal?.campaign_name;
        let group: CometChat.Group = new CometChat.Group(GUID, groupName, groupType, password, groupIcon, groupDescription);

        // Must set tags/metadata BEFORE createGroup (setTags after create does not persist)
        // Brand Messages expects tags: [campaignId, statusKey]
        const tags: string[] = [String(modal?.id), 'quotation_available'].filter(Boolean);
        group.setTags(tags);
        group.setMetadata({
            campaign_id: modal?.id,
            slug: modal?.slug,
            status: 'quotation_available',
            influencer: {
                id: userDetails?.id,
            },
        });

        CometChat.createGroup(group).then(
            (createdGroup: CometChat.Group) => {
                let membersList: CometChat.GroupMember[] = [
                    new CometChat.GroupMember(modal?.users?.id, CometChat.GROUP_MEMBER_SCOPE.ADMIN),
                    new CometChat.GroupMember(userDetails?.id, CometChat.GROUP_MEMBER_SCOPE.ADMIN),
                ];

                CometChat.addMembersToGroup(GUID, membersList, []).then(
                    (response: Object) => {
                        GUID && sendCustomMessage(GUID)
                    },
                    (error: CometChat.CometChatException) => {
                        console.log("Something went wrong", error);
                    }
                );
            }, (error: CometChat.CometChatException) => {
                console.log("Group creation failed with exception:", error);
            }
        );
    }

    const sendCustomMessage = async (GUID) => {
        let receiverID: string = GUID,
            customData: Object = {
                text: formValues.message,
                title: translations?.jobOffer,
                amount: `${translations?.amount}: $${formatNumberWithCommas(formValues?.influencer_budget)} ${modal?.currency}`,
                due: `${translations?.dueOn}: ${moment(modal?.posting_end_date).format("DD MMM YYYY")}`,
            },
            customType: string = "custom",
            receiverType: string = CometChat.RECEIVER_TYPE.GROUP,
            customMessage: CometChat.CustomMessage = new CometChat.CustomMessage(
                receiverID,
                receiverType,
                customType,
                customData
            );

        CometChat.sendCustomMessage(customMessage).then(
            (message: CometChat.CustomMessage | any) => {
                console.log("custom message sent successfully", message);
                refetch();
                mainListRefetch();
            },
            (error: CometChat.CometChatException) => {
                console.log("custom message sending failed with error", error);
            }
        );
    }

    const APIEndpoint = (modal?.campaignInfluencers?.length > 0 && (modal?.campaignInfluencers?.[0]?.status == "quotation_available") || afterQuoteStatus[modal?.campaignInfluencers?.[0]?.status]) ? `${JobEditPriceAPI}/${modal?.campaignInfluencers?.[0]?.id}` : `${JobEasyApplyAPI}/${modal?.id}`

    // Patch  API
    const { isPending, mutate } = usePost(APIEndpoint, null, async (response) => {
        if (response?.status == 200 || response?.status == 201) {
            setReviseConfirmOpen(false);
            setPendingValues(null);
            setIsApplied(true);
            let obj: any = {
                ...userDetails, invited_count: response?.data?.invited_count
            }
            dispatch(getUserDetails({ ...obj }))
            const GUID = response?.data?.campaign_influencer_id;
            if (GUID) {
                CometChat.getGroup(GUID).then(
                    (group: CometChat.Group) => {
                        GUID && sendCustomMessage(GUID)
                    }, (error: CometChat.CometChatException) => {
                        console.log("Group details fetching failed with exception:", error);
                        handleContactNow(GUID)
                    }
                );
            }
        }
    }, 'patch');

    const onApplyNow = (values) => {
        setFormValues(values)
        mutate(values)
    }

    const handleReviseContinue = () => {
        if (pendingValues) {
            onApplyNow(pendingValues);
        }
    }

    const budget = (modal?.is_barter == 'true' ? 0 : modal?.campaignInfluencers?.length > 0 && (modal?.campaignInfluencers?.[0]?.status == "quotation_available" || afterQuoteStatus[modal?.campaignInfluencers?.[0]?.status]) && !modal?.campaignInfluencers?.[0]?.is_budget_changed) ? modal?.campaignInfluencers?.[0].influencer_budget : modal?.campaignInfluencers?.[0]?.is_budget_changed ? modal?.campaignInfluencers?.[0].influencer_budget_new : modal?.budget_per_influencer

    const { mutate: mutateThumbnailUploadFile, isPending: thumbnailUploadLoader } = usePost(CommonUploadAPI, null, (response: any) => {
        if (response?.status === 200 || response?.status === 201) {
            setThumbnail(response?.data?.fileName);
            setFileParams((prev) => ({
                ...prev,
                fileName: newFileName,
                contentType: selectedFile?.type || "",
            }));
            setPreSignedUrl(true);
        }
    }, 'POST');

    const { data: preSignedUrlData, isLoading: uploadLoader } = useQuery({ queryKey: [CommonS3BucketUploadAPI, fileParams], queryFn: () => CustomFetch({ url: CommonS3BucketUploadAPI, params: { ...fileParams } }, null, false), refetchOnWindowFocus: false, enabled: !!preSignedUrl, select: (data) => data?.data });

    const handleFileChange = async (event: any) => {
        setNewFileName('');
        if (event?.target?.files && event.target.files.length > 0) {
            const file = event.target.files[0];
            setMediaType(file?.type);
            setSelectedFile(file);

            const renamed = addTimestampToFileName(file.name);
            setNewFileName(renamed);

            const imageMaxSize = 10 * 1024 * 1024; // 10 MB in bytes
            const fileMaxSize = 50 * 1024 * 1024; // 50 MB in bytes
            const videoMaxSize = 500 * 1024 * 1024; // 500 MB in bytes

            const allowedImageTypes = ["image/jpeg", "image/png", "image/webp", "image/svg+xml", "image/heic", "image/heif"];
            const allowedVideoTypes = ["video/mp4", "video/mov", "video/mkv", "video/quicktime", "video/x-msvideo", "video/x-matroska", "video/webm"];
            const allowedFileTypes = ["application/pdf", "application/vnd.oasis.opendocument.presentation", "application/vnd.oasis.opendocument.spreadsheet", "application/vnd.oasis.opendocument.text", "application/vnd.oasis.opendocument.presentation", "application/vnd.oasis.opendocument.spreadsheet", "application/vnd.oasis.opendocument.text", "application/docx", "application/xlsx", "application/pptx", "application/vnd.ms-word", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/rtf", "application/vnd.oasis.opendocument.presentation", "application/vnd.oasis.opendocument.spreadsheet", "application/vnd.oasis.opendocument.text", "application/vnd.oasis.opendocument.presentation", "application/vnd.oasis.opendocument.spreadsheet", "application/vnd.oasis.opendocument.text", "application/docx", "application/xlsx", "application/pptx", "application/vnd.ms-word", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/rtf", "application/docx", "application/xlsx", "application/pptx", "application/vnd.ms-word", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/rtf", "application/docx", "application/xlsx", "application/pptx", "application/vnd.ms-word", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/rtf", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.openxmlformats-officedocument.presentationml.presentation", "application/vnd.oasis.opendocument.presentation", "application/vnd.oasis.opendocument.spreadsheet", "application/vnd.oasis.opendocument.text", "application/docx", "application/xlsx", "application/pptx", "application/vnd.ms-word", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/rtf"];

            // Check file size
            if (allowedImageTypes.includes(file.type) && file.size > imageMaxSize) {
                CustomToast("error", translations?.draftImageValidation.replace(":imageSize", (imageMaxSize / 1024 / 1024)));
                return;
            }

            if (allowedVideoTypes.includes(file.type) && file.size > videoMaxSize) {
                CustomToast("error", translations?.draftVideoValidation.replace(":videoSize", (videoMaxSize / 1024 / 1024)));
                return;
            }

            if (allowedFileTypes.includes(file.type) && file.size > fileMaxSize) {
                CustomToast("error", translations?.draftDocValidation.replace(":docSize", (fileMaxSize / 1024 / 1024)));
                return;
            }

            let body: any = { root: "files", type: "campaign", fileName: renamed, contentType: file?.type };

            if (file?.type?.includes('video')) {
                extractVideoThumbnail(file);
            } else {
                setFileParams(body);
                setPreSignedUrl(true);
            }
        }
    };

    const addTimestampToFileName = (fileName: string) => {
        const safeName = fileName.replace(/\s+/g, "_");
        const timestamp = new Date().toISOString();
        const dotIndex = safeName.lastIndexOf(".");
        if (dotIndex === -1) {
            return `${fileName}_${timestamp}`;
        }
        const name = fileName.substring(0, dotIndex);
        const ext = fileName.substring(dotIndex);
        return `${name}_${timestamp}${ext}`;
    }

    useEffect(() => {
        const uploadToS3 = async () => {
            if (!selectedFile || !preSignedUrlData || !newFileName) return;

            if (fileParams.fileName !== newFileName) return;

            setUploadS3Loader(true);

            try {
                const upload = await fetch(preSignedUrlData?.url, {
                    method: "PUT",
                    headers: {
                        "Content-Type": selectedFile.type
                    },
                    body: selectedFile,
                });

                if (upload.ok) {
                    const newFile = { fileName: newFileName, fileType: mediaType, fileUrl: userDetails?.campaign_path + newFileName, thumbnail: thumbnail };
                    setUploadedFiles((prevFiles) => [...prevFiles, newFile]);
                } else {
                    CustomToast("error", "❌ Upload failed");
                }
            } catch (err) {
                console.error(err);
                CustomToast("error", "Upload error occurred");
            } finally {
                setUploadS3Loader(false);
                setPreSignedUrl(false);
            }
        };
        uploadToS3();
    }, [newFileName, preSignedUrlData, thumbnail]);

    const extractVideoThumbnail = (videoFile) => {
        const video = document.createElement("video");
        const canvas = document.createElement("canvas");
        const ctx: any = canvas.getContext("2d");

        video.src = URL.createObjectURL(videoFile);
        video.crossOrigin = "anonymous";
        video.muted = true;
        video.playsInline = true;

        console.log("video", video);


        video.addEventListener("loadeddata", () => {
            // Seek to 1 second in the video
            video.currentTime = 1;
        });

        video.addEventListener("seeked", () => {
            // Set canvas size to video size
            canvas.width = video.videoWidth;
            canvas.height = video.videoHeight;

            // Draw the video frame onto the canvas
            ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

            // Convert canvas to an image URL (base64)
            const thumbnailBase64 = canvas.toDataURL("image/jpeg");

            console.log("Thumbnail extracted:", thumbnailBase64);
            base64ToBlob(thumbnailBase64);

        });

        // Handle video errors
        video.addEventListener("error", (error) => {
            console.error("Error loading video: ", error);
        });
    };

    // Convert Base64 to Blob
    const base64ToBlob = (base64Data) => {
        console.log("base64Data", base64Data);

        const byteString = atob(base64Data.split(",")[1]);
        const mimeType = base64Data.split(",")[0].split(":")[1].split(";")[0]; // Get MIME type
        const arrayBuffer = new ArrayBuffer(byteString.length);
        const uintArray = new Uint8Array(arrayBuffer);

        for (let i = 0; i < byteString.length; i++) {
            uintArray[i] = byteString.charCodeAt(i);
        }

        const blob = new Blob([uintArray], { type: mimeType });

        // Convert Blob to File
        const file = new File([blob], `thumbnail_${Date.now()}.jpg`, { type: mimeType });

        // Upload file
        let formData: any = new FormData();
        formData.append('file', file);
        formData.append('type', 'campaign');
        formData.append('root', "files");

        mutateThumbnailUploadFile(formData);
    };

    const handleRemoveFile = (fileName) => {
        setUploadedFiles((prevFiles) => prevFiles.filter((file) => file.fileName !== fileName));
    };

    useEffect(() => {
        if (modal?.campaignInfluencers?.[0]?.attachment?.length > 0) {
            setUploadedFiles(modal?.campaignInfluencers?.[0]?.attachment);
        }
    }, [modal?.campaignInfluencers?.[0]?.attachment])



    return (
        <>
            <Modal modalSize={`${isApplied ? "md:w-2/3 2xl:w-1/2" : "sm:w-full lg:w-1/2 max-lg:max-w-lg max-md:max-w-sm xl:w-2/5 2xl:w-1/3"}`} modal={modal} setModal={setModal} childMainClass="!p-0 max-h-[90vh] overflow-y-auto">
                {!isApplied ?
                    <div className="flex flex-col md:gap-5 gap-2.5 md:p-5 p-2.5">
                        <div className="flex md:items-center max-md:flex-col justify-between max-md:gap-1.5">
                            {modal?.campaignInfluencers?.length > 0 ?
                                <h5 className="text-lg font-semibold">{translations?.editPrice}</h5> :
                                <h5 className="text-lg font-semibold">{translations?.applyTo} <span className="text-primary">{modal?.users?.company_name}</span></h5>
                            }
                            <div className="flex items-center gap-3">
                                {modal?.product_value > 0 && <div className="flex md:flex-col max-md:items-center max-md:gap-1">
                                    <span className="text-primary text-base font-medium leading-tight">${formatNumberWithCommas(modal?.product_value)} {modal?.currency}</span>
                                    <span className="leading-tight font-medium text-xs"><span role="img" aria-label="cash" className="mr-1">🎁</span>{translations?.productValue}</span>
                                </div>}
                                {modal?.budget_per_influencer > 0 && <div className="flex md:flex-col max-md:items-center max-md:gap-1">
                                    <span className="text-primary text-base font-medium leading-tight">${formatNumberWithCommas(modal?.budget_per_influencer)} {modal?.currency}</span>
                                    <span className="leading-tight font-medium text-xs"><span role="img" aria-label="cash" className="mr-1">💰</span>{translations?.cash}</span>
                                </div>}
                            </div>
                        </div>
                        <div className="flex items-center gap-2.5 bg-primary/10 rounded-xl py-5 px-4">
                            <div className="min-w-12 w-12 h-12 rounded-full overflow-hidden bg-gray">
                                <ImageWithFallback src={userDetails?.image} alt={modal?.users?.display_name} className="w-full h-full object-cover" width={48} height={48} />
                            </div>
                            <div className="flex flex-col">
                                <h6 className="text-lg font-medium">{userDetails?.display_name}</h6>
                                <span className="text-sm">{userDetails?.country}</span>
                            </div>
                        </div>
                        <Formik
                            enableReinitialize
                            initialValues={{
                                name: `${userDetails?.display_name}`,
                                influencer_budget: parseInt(budget).toString(),
                                message: modal?.campaignInfluencers?.[0]?.message ?? "",
                            }}
                            validationSchema={YupObject({
                                influencer_budget: modal?.budget_per_influencer > 0 ? RequiredIntegerWithDecimalField({ nameRequired: translations?.budgetRequired, nameContain: translations?.onlyNumberAllowed }) : Yup.number()
                                    .typeError('Please enter a valid number')
                                    .integer('Decimal values are not allowed. Please enter a whole amount')
                                    .required(translations?.budgetRequired),
                            })}
                            onSubmit={(values) => {
                                // if (uploadedFiles.length === 0) {
                                //     CustomToast("error", "Please upload at least one file.");
                                //     return;
                                // }
                                const preparedValues: any = { ...values };
                                const formattedValues = {
                                    ...preparedValues,
                                    attachment: uploadedFiles, // Include file names
                                };
                                if (afterQuoteStatus[modal?.campaignInfluencers?.[0]?.status]) {
                                    setPendingValues(formattedValues);
                                    setReviseConfirmOpen(true);
                                    return;
                                }
                                onApplyNow(formattedValues);
                            }}
                        >
                            {({ values, setFieldValue, errors }) => {
                                return (
                                    <Form>
                                        <QuickApplyForm values={values} setFieldValue={setFieldValue} userDetails={userDetails} campaignData={modal} errors={errors} translations={translations} composerRef={composerRef} />
                                        {uploadedFiles.length > 0 &&
                                            <ul className="flex items-center gap-2 flex-wrap col-span-12 mt-5">
                                                {uploadedFiles.map((file) => (
                                                    <li
                                                        key={file.id}
                                                        className="bg-lightGray/50 py-1 px-3 rounded-md flex gap-2"
                                                    >
                                                        <div className="flex flex-col">
                                                            <span className="text-xs">{file.fileName}</span>
                                                        </div>
                                                        <button
                                                            type="button"
                                                            className="text-red-600"
                                                            onClick={() => handleRemoveFile(file.fileName)}
                                                        >
                                                            <RiDeleteBin2Line className="text-lg" />
                                                        </button>
                                                    </li>
                                                ))}
                                            </ul>
                                        }
                                        <div className="flex xs:items-center justify-between max-xs:flex-col gap-3.5 mt-5">
                                            <div className="relative cursor-pointer flex items-center gap-1.5">
                                                <RiAttachment2 className="text-black/50 text-2xl" />
                                                <input type='file' hidden id='apply_attachment' accept=".jpg,.jpeg,.png,.webp,.svg,.pdf,.doc,.docx,.ppt,.pptx,.xls,.xlsx,.txt,.mp4,.mov,.mkv" className="-indent-24 border-b border-black/30 text-black w-full absolute opacity-0 outline-none top-0 left-0 z-50 h-full cursor-pointer p-0" onChange={handleFileChange} />
                                                <label htmlFor="apply_attachment" className={`description w-full cursor-pointer flex items-center text-sm ${(uploadS3Loader || uploadLoader || thumbnailUploadLoader) ? 'pointer-events-none' : ''}`}>
                                                    {translations?.attachment}
                                                    {(uploadS3Loader || uploadLoader || thumbnailUploadLoader) && <RiLoader2Fill className='animate-spin w-5 h-5 text-primary ml-2' />}
                                                </label>
                                            </div>
                                            <div className="flex items-center md:gap-3.5 gap-2 max-xs:*:flex-1">
                                                <BorderButton buttonType="button" title={translations?.cancel} onClick={() => setModal(false)} />
                                                <PrimaryButton buttonType="submit" customClass="flex items-center justify-center gap-1.5" disabled={isPending || thumbnailUploadLoader || uploadLoader || uploadS3Loader} >
                                                    {(modal?.campaignInfluencers?.length > 0 && modal?.campaignInfluencers?.[0]?.status == "quotation_available")
                                                        ? translations?.updatePrice
                                                        : afterQuoteStatus[modal?.campaignInfluencers?.[0]?.status] ? translations?.submitForApproval
                                                            : translations?.applyNow
                                                    }
                                                    {isPending && <LoaderSVG />}
                                                </PrimaryButton>
                                            </div>
                                        </div>
                                    </Form>
                                );

                            }}
                        </Formik>
                    </div> :
                    <AppliedSuccessfully setModal={setModal} setOpenSideModal={setOpenSideModal} setActiveTab={setActiveTab} campaignInfluencers={modal?.campaignInfluencers} translations={translations} setParams={setParams} params={params} onCloseSidebar={onCloseSidebar} />}
            </Modal>
            {reviseConfirmOpen && (
                <ConfirmationModal
                    modal={reviseConfirmOpen}
                    setModal={setReviseConfirmOpen}
                    loader={isPending}
                    args={{
                        title: translations?.reviseAgreedQuotation,
                        message: translations?.reviseAgreedQuotationMessage,
                        buttonText: translations?.continue,
                        icon: <InfoCircleSVG customClass="h-14 w-14 text-yellow-400" />,
                    }}
                    callbackFunction={handleReviseContinue}
                />
            )}
        </>
    )
}

export default QuickApply
