'use client';
import React, { useState } from 'react';
import {
  Dialog,
  DialogTrigger,
  DialogContent,
  DialogTitle,
  DialogDescription,
  DialogHeader,
} from '@/components/ui/dialog';
import CommonImage from '@/components/common/CommonImage';
import { Button } from '@/components/ui/button';
import {
  UnknownRecord,
  fnAny,
  HandlePaginatedRecords,
  ApiResponse,
  BucketProp,
  MixRecord,
} from '@/types';
import {
  commonUploadAttachment,
  globalApiGet,
  globalApiPost,
} from '@/services/global';
import {
  CommonAttachment,
  transformCommonAttachments,
  TransformedCommonAttachments,
} from '@/utils/transformCommonAttachments';
import ViewMediaDialog from './CommonViewMediaDialog';
import { Text } from '@/components/ui/text';
import { ConfirmDialog } from '@/components/common/ConfirmDialog';
import { ATTACHMENT_VALIDATION_COMMON } from '@/constants/attachment';
import { useAppToast } from '@/hooks/useAppToast';

const buildFormData = (
  data: any,
  formData = new FormData(),
  parentKey = '',
) => {
  if (
    typeof data === 'object' &&
    data !== null &&
    !(data instanceof File) &&
    !Array.isArray(data)
  ) {
    Object.keys(data).forEach((key) => {
      buildFormData(
        data[key],
        formData,
        parentKey ? `${parentKey}[${key}]` : key,
      );
    });
  } else if (Array.isArray(data)) {
    data.forEach((value, index) => {
      buildFormData(value, formData, `${parentKey}[${index}]`);
    });
  } else if (data !== undefined && data !== null) {
    formData.append(parentKey, data);
  }
  return formData;
};

type CommonViewAttachmentsButtonProps = {
  bucket: BucketProp['bucket'];
  recordData?: MixRecord & { [key: string]: MixRecord };
  handlePaginatedRecords: HandlePaginatedRecords;
  handleCloseTooltip: () => void;
  setActiveRow: fnAny;
  props?: UnknownRecord;
};
const CommonViewAttachmentsButton = ({
  bucket,
  recordData,
  setActiveRow,
  props,
  handlePaginatedRecords,
}: CommonViewAttachmentsButtonProps) => {
  const [open, setOpen] = useState<boolean>(false);
  const [categories, setCategories] = useState<UnknownRecord[]>([]);
  const { showError } = useAppToast();

  const handleAttachments = async () => {
    await globalApiGet<ApiResponse<MixRecord[]>>(
      `${bucket?.controller}/view-attachments/${recordData?.id}`,
    )
      .then((response) => {
        const { commonAttachments }: TransformedCommonAttachments =
          transformCommonAttachments(response as MixRecord);

        if (commonAttachments) {
          const commonData = [
            {
              uid: recordData?.id,
              id: `row_${recordData?.id}`,
              type: 'common',
              title: `Allowed: ${ATTACHMENT_VALIDATION_COMMON.label}`,
              attachments: commonAttachments,
            },
          ];
          const completedCategories = [...commonData];
          setCategories(completedCategories);
        }
      })
      .catch((error) => {
        console.error('Error loading attachments', error);
      });
  };
  const [attachments, setAttachments] = useState<Record<string, File[]>>({});
  const [savedItems, setSavedItems] = useState<Record<number, Set<number>>>({});

  const handleFileUpload = (
    categoryId: number,
    e: React.ChangeEvent<HTMLInputElement>,
    oldFileCount: number,
  ) => {
    const files = e.target.files;
    if (!files || files.length === 0) return;

    const allowedTypes = ATTACHMENT_VALIDATION_COMMON.allowedTypes;
    const maxSize = ATTACHMENT_VALIDATION_COMMON.maxFileSize * 1024 * 1024;

    const newFiles: File[] = Array.from(files).filter((file) => {
      const ext = file.name.split('.').pop()?.toLowerCase();

      if (!ext || !allowedTypes.includes(ext)) {
        showError(
          `Allowed file type only: ${ATTACHMENT_VALIDATION_COMMON.label}`,
          '',
        );
        return false;
      }

      if (file.size > maxSize) {
        showError(
          `Maximum allowed file size: ${ATTACHMENT_VALIDATION_COMMON.maxFileSize} MB`,
          '',
        );
        return false;
      }

      return true;
    });

    setAttachments((prev) => {
      const existingFiles = prev[categoryId] || [];

      const filteredFiles = newFiles.filter(
        (file) =>
          !existingFiles.some(
            (f) => f.name === file.name && f.size === file.size,
          ),
      );

      const totalFiles =
        oldFileCount + existingFiles.length + filteredFiles.length;

      if (totalFiles > ATTACHMENT_VALIDATION_COMMON.maxFiles) {
        return prev;
      }

      return {
        ...prev,
        [categoryId]: [...existingFiles, ...filteredFiles],
      };
    });

    if (
      oldFileCount + (attachments[categoryId]?.length || 0) + newFiles.length >
      ATTACHMENT_VALIDATION_COMMON.maxFiles
    ) {
      showError(
        `Maximum ${ATTACHMENT_VALIDATION_COMMON.maxFiles} files allowed`,
        '',
      );
    }

    e.target.value = '';
  };

  const handleUploadToServer = async (category: UnknownRecord) => {
    const formData = new FormData();
    const attachment = attachments[category.id as string];

    buildFormData(
      { ...attachment, type: category.type, id: category.uid },
      formData,
    );

    await commonUploadAttachment({
      endpoint: `${bucket?.controller}/add-attachment`,
      data: formData,
    });
    handleAttachments();

    setAttachments((prev) => ({
      ...prev,
      [category.id as string]: [],
    }));
    handlePaginatedRecords(1, {});
  };

  const handleRemove = (categoryId: number, index: number) => {
    setAttachments((prev) => ({
      ...prev,
      [categoryId]: prev[categoryId].filter((_, i) => i !== index),
    }));

    setSavedItems((prev) => {
      const updated = new Set(prev[categoryId] || []);
      updated.delete(index);
      return { ...prev, [categoryId]: updated };
    });
  };

  const isImageFile = (file: File) => file.type.startsWith('image/');
  const isPdfFile = (file: File) => file.type === 'application/pdf';

  function getFileExtension(fileUrl: string): string | null {
    const match = fileUrl.match(/\.(\w+)(?:\?|#|$)/);
    return match ? `${match[1].toLowerCase()}` : null;
  }

  const isExcelFile = (file: File) => {
    const excelMimeTypes = [
      'application/vnd.ms-excel',
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      'application/octet-stream',
      'application/x-excel',
      'application/x-msexcel',
      'application/excel',
    ];
    return (
      excelMimeTypes.includes(file.type) ||
      file.name.endsWith('.xls') ||
      file.name.endsWith('.xlsx')
    );
  };

  const isWordFile = (file: File) => {
    const name = file.name.toLowerCase();
    return (
      file.type === 'application/msword' ||
      file.type ===
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||
      name.endsWith('.doc') ||
      name.endsWith('.docx')
    );
  };

  const handleDownload = (file: File) => {
    const url = URL.createObjectURL(file);
    const link = document.createElement('a');
    link.href = url;
    link.download = file.name;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
  };
  const downloadFile = async (fileUrl: string) => {
    const response = await fetch(fileUrl, { mode: 'cors' });

    if (!response.ok) {
      console.error('Download failed');
      return;
    }

    const blob = await response.blob();
    const url = URL.createObjectURL(blob);

    const a = document.createElement('a');
    a.href = url;
    a.download = fileUrl.split('/').pop() || 'download'; // force name
    a.click();

    URL.revokeObjectURL(url);
  };
  const handleRemoveExisting = async (
    categoryId: number,
    attachmentToRemove: UnknownRecord,
  ) => {
    const result = await globalApiPost(
      `${bucket?.controller}/remove-attachment`,
      attachmentToRemove,
    );
    if (result) {
      setCategories((prevCategories) =>
        prevCategories.map((category) =>
          category.id === categoryId
            ? {
                ...category,
                attachments:
                  (Array.isArray(category?.attachments) &&
                    category?.attachments.filter(
                      (att: CommonAttachment) =>
                        att.id !== attachmentToRemove.id,
                    )) ||
                  [],
              }
            : category,
        ),
      );
      handlePaginatedRecords(1, {});
    }
  };

  return (
    <>
      <Dialog
        open={open}
        onOpenChange={(isOpen) => {
          setOpen(isOpen);
          if (isOpen) {
            handleAttachments();
          } else {
            setActiveRow(null);
          }
        }}
      >
        <DialogTrigger onClick={() => setOpen(true)} asChild>
          <Button className="button-action">
            <CommonImage
              src={(props?.icon as string) || '/main/view-attachments.webp'}
              width={15}
              height={15}
              alt={(props?.alt as string) || 'View Attachments'}
              classname="info-icon"
            />
          </Button>
        </DialogTrigger>
        <DialogContent
          className="z-50 w-full cross-arrow max-w-7xl p-0 m-0 view-attachment-widget modal-common-widget"
          onInteractOutside={(e) => e.preventDefault()}
          onEscapeKeyDown={(e) => e.preventDefault()}
          onClick={(e) => e.stopPropagation()}
          data-dialog-id="edit-dialog"
        >
          <DialogHeader>
            <DialogTitle className="p-5 modal-header">Attachments</DialogTitle>
            <DialogDescription>{''}</DialogDescription>
          </DialogHeader>
          <Text className="overflow-y-auto h-full DialogMiddle footer-skip">
            {categories.map((category) => (
              <div
                className="view-attachments-widget"
                key={category.id as string}
              >
                <div className="view-inner">
                  <h3 className="text-lg font-medium mb-4">
                    {category.title as string}
                  </h3>
                  <div className="list-add-widget">
                    <ul className="list-disc list-inside">
                      {Array.isArray(category?.attachments) &&
                        category.attachments.length > 0 &&
                        category.attachments.map(
                          (attachment: UnknownRecord, index: number) => (
                            <li
                              className="update-successfully"
                              key={(attachment.id as number) || index}
                            >
                              <div className="img-cont cursor-pointer">
                                {[
                                  'png',
                                  'webp',
                                  'jpg',
                                  'jpeg',
                                  'PNG',
                                  'WEBP',
                                  'JPG',
                                  'JPEG',
                                ].includes(
                                  getFileExtension(
                                    attachment.file_url as string,
                                  ) || '',
                                ) ? (
                                  <button
                                    onClick={(e) => {
                                      e.preventDefault();
                                      e.stopPropagation();
                                    }}
                                  >
                                    <CommonImage
                                      src={
                                        (attachment.file_url as string) ||
                                        '/main/media-test.webp'
                                      }
                                      width={200}
                                      height={200}
                                      alt="img view 1"
                                      classname="view-icon"
                                    />
                                  </button>
                                ) : getFileExtension(
                                    attachment.file_url as string,
                                  ) === 'pdf' ? (
                                  <button
                                    onClick={(e) => {
                                      e.preventDefault();
                                      e.stopPropagation();
                                    }}
                                  >
                                    <CommonImage
                                      src="/main/pdf-icon.webp"
                                      width={50}
                                      height={50}
                                      alt="PDF"
                                      classname="doc-icon pdf-icon"
                                    />
                                  </button>
                                ) : ['xlsx', 'csv'].includes(
                                    getFileExtension(
                                      attachment.file_url as string,
                                    ) || '',
                                  ) ? (
                                  <button
                                    onClick={(e) => {
                                      e.preventDefault();
                                      e.stopPropagation();
                                    }}
                                  >
                                    <CommonImage
                                      src="/main/excel-icon.webp"
                                      width={50}
                                      height={50}
                                      alt="Excel"
                                      classname="doc-icon excel-icon"
                                    />
                                  </button>
                                ) : ['docx', 'doc'].includes(
                                    getFileExtension(
                                      attachment.file_url as string,
                                    ) || '',
                                  ) ? (
                                  <button
                                    onClick={(e) => {
                                      e.preventDefault();
                                      e.stopPropagation();
                                    }}
                                  >
                                    <CommonImage
                                      src="/main/word-icon.webp"
                                      width={50}
                                      height={50}
                                      alt="Word"
                                      classname="doc-icon word-icon"
                                    />
                                  </button>
                                ) : (
                                  <button
                                    onClick={(e) => {
                                      e.preventDefault();
                                      e.stopPropagation();
                                    }}
                                  >
                                    <CommonImage
                                      src="/main/file-icon.webp"
                                      width={50}
                                      height={50}
                                      alt="File"
                                      classname="doc-icon file-icon"
                                    />
                                  </button>
                                )}
                              </div>

                              <div className="attach-footer success">
                                <ViewMediaDialog
                                  files={[
                                    ...(Array.isArray(category.attachments)
                                      ? category.attachments.map(
                                          (att: UnknownRecord) => ({
                                            file_url: String(att.file_url),
                                            name: String(
                                              att.file_name ||
                                                att.name ||
                                                `file_${att.id}`,
                                            ),
                                            type: String(att.type || ''),
                                          }),
                                        )
                                      : []),
                                    ...(attachments[category.id as number] ||
                                      []),
                                  ]}
                                  initialIndex={index}
                                />
                                {bucket?.table_row_actions
                                  ?.download_attachment && (
                                  <button
                                    className="attach-download"
                                    onClick={() => {
                                      downloadFile(`${attachment.file_url}`);
                                    }}
                                  >
                                    <CommonImage
                                      src="/main/attach-downloads.webp"
                                      width={18}
                                      height={18}
                                      alt="Download File"
                                      classname="downloads-icon"
                                    />
                                  </button>
                                )}
                                {bucket?.table_row_actions
                                  ?.remove_attachment && (
                                  <button className="closed-box">
                                    <ConfirmDialog
                                      message="Do you want to remove this file?"
                                      onConfirm={() =>
                                        handleRemoveExisting(
                                          category.id as number,
                                          attachment,
                                        )
                                      }
                                      trigger={
                                        <span>
                                          <CommonImage
                                            src="/main/delete-attach.png"
                                            width={10}
                                            height={10}
                                            alt="Delete File"
                                            classname="cross-icon"
                                          />
                                        </span>
                                      }
                                    />
                                  </button>
                                )}
                              </div>
                            </li>
                          ),
                        )}

                      {(attachments[category.id as string] || []).map(
                        (file, index) => (
                          <li key={index} className=" update-pending">
                            <div
                              className="img-cont cursor-pointer"
                              onClick={(e) => {
                                e.preventDefault();
                                e.stopPropagation();
                              }}
                            >
                              {isImageFile(file) ? (
                                <button
                                  onClick={(e) => {
                                    e.preventDefault();
                                    e.stopPropagation();
                                  }}
                                >
                                  <CommonImage
                                    src={URL.createObjectURL(file)}
                                    width={200}
                                    height={200}
                                    alt="view"
                                    classname="view-icon"
                                  />
                                </button>
                              ) : isPdfFile(file) ? (
                                <button
                                  onClick={(e) => {
                                    e.preventDefault();
                                    e.stopPropagation();
                                  }}
                                >
                                  <CommonImage
                                    src="/main/pdf-icon.webp"
                                    width={50}
                                    height={50}
                                    alt="PDF"
                                    classname="doc-icon pdf-icon"
                                  />
                                </button>
                              ) : isExcelFile(file) ? (
                                <button
                                  onClick={(e) => {
                                    e.preventDefault();
                                    e.stopPropagation();
                                  }}
                                >
                                  <CommonImage
                                    src="/main/excel-icon.webp"
                                    width={50}
                                    height={50}
                                    alt="Excel"
                                    classname="doc-icon excel-icon"
                                  />
                                </button>
                              ) : isWordFile(file) ? (
                                <button
                                  onClick={(e) => {
                                    e.preventDefault();
                                    e.stopPropagation();
                                  }}
                                >
                                  <CommonImage
                                    src="/main/word-icon.webp"
                                    width={50}
                                    height={50}
                                    alt="Word"
                                    classname="doc-icon word-icon"
                                  />
                                </button>
                              ) : (
                                <button
                                  onClick={(e) => {
                                    e.preventDefault();
                                    e.stopPropagation();
                                  }}
                                >
                                  <CommonImage
                                    src="/main/file-icon.webp"
                                    width={50}
                                    height={50}
                                    alt="File"
                                    classname="doc-icon file-icon"
                                  />
                                </button>
                              )}
                            </div>

                            <div className="attach-footer pending">
                              {((Array.isArray(category.attachments) &&
                                category.attachments.length) ||
                                0) +
                                (attachments[String(category.id)]?.length ||
                                  0) >
                                0 && (
                                <ViewMediaDialog
                                  files={[
                                    ...(Array.isArray(category.attachments)
                                      ? category.attachments.map(
                                          (att: UnknownRecord) => ({
                                            file_url: String(att.file_url),
                                            name: String(
                                              att.file_name ||
                                                att.name ||
                                                `file_${att.id}`,
                                            ),
                                            type: String(att.type || ''),
                                          }),
                                        )
                                      : []),
                                    ...(attachments[String(category.id)] || []),
                                  ]}
                                  initialIndex={
                                    index +
                                    ((Array.isArray(category.attachments) &&
                                      category.attachments.length) ||
                                      0)
                                  }
                                />
                              )}

                              <button
                                className="attach-download"
                                onClick={() => handleDownload(file)}
                                title="Download"
                              >
                                <CommonImage
                                  src="/main/attach-downloads.webp"
                                  width={18}
                                  height={18}
                                  alt="Download File"
                                  classname="downloads-icon"
                                />
                              </button>

                              {bucket?.table_row_actions?.remove_attachment && (
                                <button className="closed-box" title="Delete">
                                  <ConfirmDialog
                                    message="Do you want to remove this file?"
                                    onConfirm={() =>
                                      handleRemove(category.id as number, index)
                                    }
                                    trigger={
                                      <span>
                                        <CommonImage
                                          src="/main/delete-attach.png"
                                          width={10}
                                          height={10}
                                          alt="Delete File"
                                          classname="cross-icon"
                                        />
                                      </span>
                                    }
                                  />
                                </button>
                              )}

                              {/* <button className="attach-upload">
                              <CommonImage
                                src="/main/attach-icon-upload.webp"
                                width={22}
                                height={22}
                                alt="downloads"
                                classname="downloads-icon"
                              />
                            </button> */}
                            </div>
                          </li>
                        ),
                      )}
                    </ul>
                    <div className="add-more-attach">
                      {attachments[category.id as number] &&
                        attachments[category.id as number].length > 0 && (
                          <button
                            className={`attach-save ${
                              savedItems[category.id as number]?.size ===
                              attachments[category.id as number].length
                                ? 'active'
                                : ''
                            }`}
                            disabled={
                              savedItems[category.id as number]?.size ===
                              attachments[category.id as number].length
                            }
                            onClick={() => {
                              setSavedItems((prev) => ({
                                ...prev,
                                [category.id as number]: new Set(
                                  attachments[category.id as number].map(
                                    (_, idx) => idx,
                                  ),
                                ),
                              }));
                              handleUploadToServer(category);
                            }}
                          >
                            <CommonImage
                              src="/main/check-mark.webp"
                              width={18}
                              height={18}
                              alt="Save File(s)"
                              classname="save-icon"
                            />
                          </button>
                        )}

                      {bucket?.table_row_actions?.add_attachment && (
                        <label className="attach-add-button">
                          <input
                            type="file"
                            className="hidden"
                            multiple
                            accept={ATTACHMENT_VALIDATION_COMMON.allowedTypes
                              .map((t) => `.${t}`)
                              .join(',')}
                            onChange={(e) =>
                              handleFileUpload(
                                category.id as number,
                                e,
                                category.attachments.length as number,
                              )
                            }
                          />
                          <CommonImage
                            src="/main/add-icn.webp"
                            width={18}
                            height={18}
                            alt="Add File"
                            classname="downloads-icon"
                          />
                        </label>
                      )}
                    </div>
                  </div>
                </div>
              </div>
            ))}
          </Text>
        </DialogContent>
      </Dialog>
    </>
  );
};
export default CommonViewAttachmentsButton;
