import React, { useEffect } from "react";
import { useModal } from "../../hooks/useAuth";
import Modal from "../common/Modal";
import { FormProvider, useForm } from "react-hook-form";
import Label from "../common/Label";
import { zodResolver } from "@hookform/resolvers/zod";
import { defaultCollection, newCollection } from "./collectionSchema";
import SelectMultiple from "../common/SelectMultiple";
import { useProjectName } from "../../hooks/useProjects";
import DatePicker from "../common/DatePicker";
import {
  useCollection,
  useCreateCollection,
  useUpdateCollection,
} from "../../hooks/useCollections";
import { formatFileSize, localToUtc } from "../../utils/appUtils";
import { useCollectionContext } from "../../pages/collections/CollectionPage";
import { formatDate } from "../../utils/dateUtils";

const ManageCollection = ({ collectionId, onClose }) => {
  const { data, isError, isLoading, error } = useCollection(collectionId);
  const { projectNames, projectLoading } = useProjectName(true);
  const methods = useForm({
    resolver: zodResolver(newCollection),
    defaultValues: defaultCollection,
  });
  const {
    control,
    watch,
    register,
    setValue,
    handleSubmit,
    reset,
    formState: { errors },
  } = methods;

  const { mutate: createNewCollection, isPending } = useCreateCollection(() => {
    handleClose();
  });
  const { mutate: UpdateCollection } = useUpdateCollection(() => {
    handleClose();
  });

  const files = watch("attachments");
  const onFileChange = async (e) => {
    const newFiles = Array.from(e.target.files);
    if (newFiles.length === 0) return;

    const existingFiles = watch("attachments") || [];

    const parsedFiles = await Promise.all(
      newFiles.map(async (file) => {
        const base64Data = await toBase64(file);
        return {
          fileName: file.name,
          base64Data,
          contentType: file.type,
          fileSize: file.size,
          description: "",
          isActive: true,
        };
      })
    );

    const combinedFiles = [
      ...existingFiles,
      ...parsedFiles.filter(
        (newFile) =>
          !existingFiles.some(
            (f) =>
              f.fileName === newFile.fileName && f.fileSize === newFile.fileSize
          )
      ),
    ];

    setValue("attachments", combinedFiles, {
      shouldDirty: true,
      shouldValidate: true,
    });
  };

  const toBase64 = (file) =>
    new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => resolve(reader.result.split(",")[1]);
      reader.onerror = (error) => reject(error);
    });
  const removeFile = (index) => {
    if (collectionId) {
      const newFiles = files.map((file, i) => {
        if (file.documentId !== index) return file;
        return {
          ...file,
          isActive: false,
        };
      });
      setValue("attachments", newFiles, { shouldValidate: true });
    } else {
      const newFiles = files.filter((_, i) => i !== index);
      setValue("attachments", newFiles, { shouldValidate: true });
    }
  };

  const onSubmit = (formData) => {
    const payload = {
      ...formData,
      clientSubmitedDate: localToUtc(formData.clientSubmitedDate),
      invoiceDate: localToUtc(formData.invoiceDate),
      exceptedPaymentDate: localToUtc(formData.exceptedPaymentDate),
    };

    if (collectionId) {
      UpdateCollection({
        collectionId,
        payload: { ...payload, id: collectionId },
      });
    } else {
      createNewCollection(payload);
    }
  };

  const handleClose = () => {
    reset(defaultCollection);
    onClose();
  };

  useEffect(() => {
    if (data && collectionId) {
      reset({
        projectId: data?.project?.id,
        invoiceNumber: data?.invoiceNumber,
        eInvoiceNumber: data?.eInvoiceNumber,
        title: data?.title,
        clientSubmitedDate: formatDate(data?.clientSubmitedDate),
        invoiceDate: formatDate(data?.invoiceDate),
        exceptedPaymentDate: formatDate(data?.exceptedPaymentDate),
        taxAmount: data?.taxAmount,
        basicAmount: data?.basicAmount,
        description: data?.description,
        attachments: data.attachments
          ? data.attachments.map((doc) => ({
              fileName: doc.fileName,
              base64Data: null,
              contentType: doc.contentType,
              documentId: doc.documentId,
              fileSize: 0,
              description: "",
              preSignedUrl: doc.preSignedUrl,
              isActive: doc.isActive ?? true,
            }))
          : [],
      });
    }
  }, [data]);
  if (isLoading) return <div>Loading....</div>;
  if (isError) return <div>{error.message}</div>;
  return (
    <div className="container pb-3">
      <div className="text-black fs-5 mb-2">
        {collectionId ? "Update" : "New"} Collection
      </div>
      <FormProvider {...methods}>
        <form onSubmit={handleSubmit(onSubmit)} className="p-0 text-start">
          <div className="row px-md-1 px-0">
            <div className="col-12 col-md-6  mb-2">
              <Label className="form-label" required>
                Select Project
              </Label>
              <select
                className="form-select form-select-sm"
                {...register("projectId")}
              >
                <option value="">Select Project</option>
                {projectLoading ? (
                  <option>Loading...</option>
                ) : (
                  projectNames?.map((project) => (
                    <option key={project.id} value={project.id}>
                      {project.name}
                    </option>
                  ))
                )}
              </select>
              {errors.projectId && (
                <small className="danger-text">
                  {errors.projectId.message}
                </small>
              )}
            </div>
            <div className="col-12 col-md-6 mb-2">
              <Label required>Title</Label>
              <input
                type="text"
                className="form-control form-control-sm"
                {...register("title")}
              />
              {errors.title && (
                <small className="danger-text">{errors.title.message}</small>
              )}
            </div>
            <div className="col-12 col-md-6  mb-2">
              <Label required>Invoice Number</Label>
              <input
                type="text"
                className="form-control form-control-sm"
                {...register("invoiceNumber")}
              />
              {errors.invoiceId && (
                <small className="danger-text">
                  {errors.invoiceId.message}
                </small>
              )}
            </div>
            <div className="col-12 col-md-6  mb-2">
              <Label required>E-Invoice Number</Label>
              <input
                type="text"
                className="form-control form-control-sm"
                {...register("eInvoiceNumber")}
              />
              {errors.invoiceId && (
                <small className="danger-text">
                  {errors.invoiceId.message}
                </small>
              )}
            </div>
            <div className="col-12 col-md-6  mb-2">
              <Label required>Invoice Date</Label>
              <DatePicker
                name="invoiceDate"
                control={control}
                maxDate={new Date()}
              />
              {errors.invoiceDate && (
                <small className="danger-text">
                  {errors.invoiceDate.message}
                </small>
              )}
            </div>
            <div className="col-12 col-md-6  mb-2">
              <Label required>Expected Payment Date</Label>
              <DatePicker
                name="exceptedPaymentDate"
                control={control}
                minDate={watch("invoiceDate")}
              />
              {errors.exceptedPaymentDate && (
                <small className="danger-text">
                  {errors.exceptedPaymentDate.message}
                </small>
              )}
            </div>
            <div className="col-12 col-md-6  mb-2">
              <Label required>Submission Date (Client)</Label>
              <DatePicker
                name="clientSubmitedDate"
                control={control}
                maxDate={new Date()}
              />
              {errors.exceptedPaymentDate && (
                <small className="danger-text">
                  {errors.exceptedPaymentDate.message}
                </small>
              )}
            </div>

            <div className="col-12 col-md-6  mb-2">
              <Label htmlFor="basicAmount" className="form-label" required>
                Basic Amount
              </Label>
              <input
                type="number"
                id="basicAmount"
                className="form-control form-control-sm"
                min="1"
                step="0.01"
                inputMode="decimal"
                {...register("basicAmount", { valueAsNumber: true })}
              />
              {errors.basicAmount && (
                <small className="danger-text">
                  {errors.basicAmount.message}
                </small>
              )}
            </div>
            <div className="col-12 col-md-6  mb-2">
              <Label htmlFor="taxAmount" className="form-label" required>
                Tax Amount
              </Label>
              <input
                type="number"
                id="taxAmount"
                className="form-control form-control-sm"
                min="1"
                step="0.01"
                inputMode="decimal"
                {...register("taxAmount", { valueAsNumber: true })}
              />
              {errors.taxAmount && (
                <small className="danger-text">
                  {errors.taxAmount.message}
                </small>
              )}
            </div>
            <div className="col-12 my-2 text-start  mb-2">
              <div className="col-md-12">
                <Label htmlFor="description" className="form-label" required>
                  Description
                </Label>
                <textarea
                  id="description"
                  className="form-control form-control-sm"
                  {...register("description")}
                  rows="2"
                ></textarea>
                {errors.description && (
                  <small className="danger-text">
                    {errors.description.message}
                  </small>
                )}
              </div>
            </div>

            <div className="col-12">
              <Label className="form-label" required>
                Upload Bill{" "}
              </Label>

              <div
                className="border border-secondary border-dashed rounded p-4 text-center bg-textMuted position-relative text-black"
                style={{ cursor: "pointer" }}
                onClick={() => document.getElementById("attachments").click()}
              >
                <i className="bx bx-cloud-upload d-block bx-lg "> </i>
                <span className="text-muted d-block">
                  Click to select or click here to browse
                </span>
                <small className="text-muted">
                  (PDF, JPG, PNG,Doc,docx,xls,xlsx max 5MB)
                </small>

                <input
                  type="file"
                  id="attachments"
                  accept="
    .pdf,
    .doc,
    .docx,
    .xls,
    .xlsx,
    .jpg,
    .jpeg,
    .png
  "
                  multiple
                  style={{ display: "none" }}
                  {...register("attachments")}
                  onChange={(e) => {
                    onFileChange(e);
                    e.target.value = "";
                  }}
                />
              </div>
              {errors.attachments && (
                <small className="danger-text">
                  {errors.attachments.message}
                </small>
              )}
              {files.length > 0 && (
                <div className="d-block">
                  {files
                    .filter((file) => {
                      if (collectionId) {
                        return file.isActive;
                      }
                      return true;
                    })
                    .map((file, idx) => (
                      <a
                        key={idx}
                        className="d-flex justify-content-between text-start p-1"
                        href={file.preSignedUrl || "#"}
                        target="_blank"
                        rel="noopener noreferrer"
                      >
                        <div>
                          <span className="mb-0 text-secondary small d-block">
                            {file.fileName}
                          </span>
                          <span className="text-body-secondary small d-block">
                            {file.fileSize ? formatFileSize(file.fileSize) : ""}
                          </span>
                        </div>
                        <i
                          className="bx bx-trash bx-sm cursor-pointer text-danger"
                          onClick={(e) => {
                            e.preventDefault();
                            removeFile(collectionId ? file.documentId : idx);
                          }}
                        ></i>
                      </a>
                    ))}
                </div>
              )}

              {Array.isArray(errors.attachments) &&
                errors.attachments.map((fileError, index) => (
                  <div key={index} className="danger-text small mt-1">
                    {
                      (fileError?.fileSize?.message ||
                        fileError?.contentType?.message ||
                        fileError?.base64Data?.message,
                      fileError?.documentId?.message)
                    }
                  </div>
                ))}
            </div>

            <div className="d-flex justify-content-end gap-3">
              {" "}
              <button
                type="reset"
                className="btn btn-label-secondary btn-sm mt-3"
                onClick={handleClose}
                disabled={isPending}
              >
                Cancel
              </button>
              <button
                type="submit"
                className="btn btn-primary btn-sm mt-3"
                disabled={isPending}
              >
                {isPending ? "Please Wait..." : "Submit"}
              </button>
            </div>
          </div>
        </form>
      </FormProvider>
    </div>
  );
};

export default ManageCollection;
