import { zodResolver } from "@hookform/resolvers/zod";
import React, { useEffect, useState } from "react";
import { useForm, FormProvider } from "react-hook-form";
import { defaultDocumentValues, DocumentPayloadSchema } from "./DocumentSchema";
import Label from "../common/Label";
import {
  useDocumentCategories,
  useDocumentTypes,
} from "../../hooks/masterHook/useMaster";
import TagInput from "../common/TagInput";
import { useUploadDocument } from "../../hooks/useDocument";
import showToast from "../../services/toastService";

const toBase64 = (file) =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = (err) => reject(err);
  });

const NewDocument = ({closeModal,Document_Entity,Entity}) => {

  const [selectedType, setSelectedType] = useState(null);
  const [selectedCategory, setSelectedCategory] = useState(null);
  const [schema, setSchema] = useState(() => DocumentPayloadSchema({}));
  const methods = useForm({
    resolver: zodResolver(schema),
    defaultValues: defaultDocumentValues,
  });

  const {
    register,
    handleSubmit,
    watch,
    setValue,
    reset,
    formState: { errors },
  } = methods;
  const { mutate: UploadDocument, isPending } = useUploadDocument(() => {
    showToast("Document Uploaded Successfully", "success");
    closeModal();
  });
  const onSubmit = (data) => {
    const DocumentPayload = { ...data, entityId: Entity };
    UploadDocument(DocumentPayload);
  };

  const file = watch("attachment");

  const documentTypeId = watch("documentTypeId");

  // This hooks calling api base Entity(Employee) and Category
  const { DocumentCategories, isLoading } = useDocumentCategories(
     Document_Entity
  );

  const categoryId = watch("documentCategoryId");
  const { DocumentTypes, isLoading: isTypeLoading } = useDocumentTypes(
    categoryId || null
  );

  // Update schema whenever document type changes
  useEffect(() => {
    if (!documentTypeId) return;
    const type = DocumentTypes?.find((t) => t.id === documentTypeId);
    setSelectedType(type || null);

    if (type) {
      const newSchema = DocumentPayloadSchema({
        isMandatory: type.isMandatory ?? false,
        regexExpression: type.regexExpression ?? null,
        allowedContentType: type.allowedContentType ?? [
          "application/pdf",
          "image/jpeg",
          "image/png",
        ],
        maxSizeAllowedInMB: type.maxSizeAllowedInMB ?? 25,
      });

      setSchema(() => newSchema);

      reset({ ...methods.getValues() }, { keepValues: true });
    }
  }, [documentTypeId, DocumentTypes, reset]);

  // File Upload
  const onFileChange = async (e) => {
    const uploaded = e.target.files[0];
    if (!uploaded) return;

    const base64Data = await toBase64(uploaded);

    const parsedFile = {
      fileName: uploaded.name,
      base64Data,
      contentType: uploaded.type,
      fileSize: uploaded.size,
      description: "",
      isActive: true,
    };

    setValue("attachment", parsedFile, {
      shouldDirty: true,
      shouldValidate: true,
    });
  };

  const removeFile = () => {
    setValue("attachment", null, {
      shouldDirty: true,
      shouldValidate: true,
    });
  };

  // build dynamic file accept string
  const fileAccept =
    selectedType?.allowedContentType
      ?.split(",")
      .map((t) =>
        t === "application/pdf"
          ? ".pdf"
          : t === "image/jpeg"
          ? ".jpg,.jpeg"
          : t === "image/png"
          ? ".png"
          : ""
      )
      .join(",") || "";
  return (
    <div className="p-2">
      <p className="fw-bold fs-6">Upload New Document</p>
      <FormProvider key={documentTypeId} {...methods}>
        <form onSubmit={handleSubmit(onSubmit)}>
          {/* Document Name */}
          <div className="mb-2">
            <Label htmlFor="name" required>
              Document Name
            </Label>
            <input
              type="text"
              className="form-control form-control-sm"
              {...register("name")}
            />
            {errors.name && (
              <div className="danger-text">{errors.name.message}</div>
            )}
          </div>

          {/* Category */}
          <div className="mb-2">
            <Label htmlFor="documentCategoryId">Document Category</Label>
            <select
              {...register("documentCategoryId")}
              className="form-select form-select-sm"
            >
              {isLoading && (
                <option disabled value="">
                  Loading...
                </option>
              )}
              {!isLoading && <option value="">Select Category</option>}
              {DocumentCategories?.map((type) => (
                <option key={type.id} value={type.id}>
                  {type.name}
                </option>
              ))}
            </select>
            {errors.documentCategoryId && (
              <div className="danger-text">
                {errors.documentCategoryId.message}
              </div>
            )}
          </div>

          {/* Type */}
          {categoryId && (<div className="mb-2">
            <Label htmlFor="documentTypeId">Document Type</Label>
            <select
              {...register("documentTypeId")}
              className="form-select form-select-sm"
            >
              {isTypeLoading && (
                <option disabled value="">
                  Loading...
                </option>
              )}
              {DocumentTypes?.map((type) => (
                <option key={type.id} value={type.id}>
                  {type.name}
                </option>
              ))}
            </select>
            {errors.documentTypeId && (
              <div className="danger-text">{errors.documentTypeId.message}</div>
            )}
          </div>)}
          

          {/* Document ID */}
          <div className="mb-2">
            <Label
              htmlFor="documentId"
              required={selectedType?.isMandatory ?? false}
            >
              Document ID
            </Label>
            <input
              type="text"
              className="form-control form-control-sm"
              {...register("documentId")}
            />
            {errors.documentId && (
              <div className="danger-text">{errors.documentId.message}</div>
            )}
          </div>

          {/* Upload */}
          <div className="row my-2">
            <div className="col-md-12">
              <label className="form-label">Upload Document</label>

              <div
                className="border border-secondary border-dashed rounded p-4 text-center bg-textMuted position-relative"
                style={{ cursor: "pointer" }}
                onClick={() => document.getElementById("attachment").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">
                  ({selectedType?.allowedContentType || "PDF/JPG/PNG"}, max{" "}
                  {selectedType?.maxSizeAllowedInMB ?? 25}MB)
                </small>

                <input
                  type="file"
                  id="attachment"
                  accept={selectedType?.allowedContentType}
                  style={{ display: "none" }}
                  onChange={(e) => {
                    onFileChange(e);
                    e.target.value = ""; // reset input
                  }}
                />
              </div>

              {errors.attachment && (
                <small className="danger-text">
                  {errors.attachment.message
                    ? errors.attachment.message
                    : errors.attachment.fileName?.message ||
                      errors.attachment.base64Data?.message ||
                      errors.attachment.contentType?.message ||
                      errors.attachment.fileSize?.message}
                </small>
              )}

              {file?.base64Data && (
                <div className="d-flex justify-content-between text-start p-1 mt-2">
                  <div>
                    <span className="mb-0 text-secondary small d-block">
                      {file.fileName}
                    </span>
                    <span className="text-body-secondary small d-block">
                      {(file.fileSize / 1024).toFixed(1)} KB
                    </span>
                  </div>
                  <i
                    className="bx bx-trash bx-sm cursor-pointer text-danger"
                    onClick={removeFile}
                  ></i>
                </div>
              )}
            </div>
          </div>
          <div className="mb-2">
            <TagInput name="tags" label="Tags" placeholder="Tags.." />
            {errors.tags && (
              <small className="danger-text">{errors.tags.message}</small>
            )}
          </div>

          {/* Description */}
          <div className="mb-2">
            <Label htmlFor="description">Description</Label>
            <textarea
              rows="2"
              className="form-control"
              {...register("description")}
            ></textarea>
            {errors.description && (
              <div className="danger-text">{errors.description.message}</div>
            )}
          </div>

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

export default NewDocument;
