import React, { useMemo, useState } from "react";
import DatePicker from "../common/DatePicker";
import EmployeeSearchInput from "../common/EmployeeSearchInput";
import Label from "../common/Label";
import { zodResolver } from "@hookform/resolvers/zod";
import {
  defaultPRActionValues,
  PaymentRequestActionScheam,
} from "./PaymentRequestSchema";
import {
  useActionOnPaymentRequest,
  usePaymentRequestDetail,
} from "../../hooks/useExpense";
import {
  CREATE_EXEPENSE,
  EXPENSE_CREATE,
  EXPENSE_PROCESSED,
  EXPENSE_REJECTEDBY,
  PROCESS_EXPENSE,
  REVIEW_EXPENSE,
} from "../../utils/constants";
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import { useNavigate } from "react-router-dom";
import { useForm } from "react-hook-form";
import { useSelector } from "react-redux";
import { usePaymentRequestContext } from "../../pages/PaymentRequest/PaymentRequestPage";
import { localToUtc } from "../../utils/appUtils";
import { usePaymentMode } from "../../hooks/masterHook/useMaster";
import Filelist from "../Expenses/Filelist";

const ActionPaymentRequest = ({ requestId }) => {
  const { setIsExpenseGenerate, setVieRequest } = usePaymentRequestContext();
  const { data, isLoading, isError, error, isFetching } =
    usePaymentRequestDetail(requestId);
  const [IsPaymentProcess, setIsPaymentProcess] = useState(false);
  const [clickedStatusId, setClickedStatusId] = useState(null);
  const {
    PaymentModes,
    loading: PaymentModeLoading,
    error: PaymentModeError,
  } = usePaymentMode();

  const IsReview = useHasUserPermission(REVIEW_EXPENSE);
  const [imageLoaded, setImageLoaded] = useState({});

  const isRejectedRequest = useMemo(() => {
    return EXPENSE_REJECTEDBY.includes(data?.status?.id);
  }, [data]);
  const isProccesed = useMemo(() => {
    return data?.expenseStatus?.id === EXPENSE_PROCESSED;
  }, [data]);
  const ActionSchema =
    PaymentRequestActionScheam(IsPaymentProcess, isProccesed) ?? z.object({});
  const navigate = useNavigate();
  const {
    register,
    handleSubmit,
    setValue,
    reset,
    control,
    watch,
    formState: { errors },
  } = useForm({
    resolver: zodResolver(ActionSchema),
    defaultValues: defaultPRActionValues,
  });

  const userPermissions = useSelector(
    (state) => state?.globalVariables?.loginUser?.featurePermissions || []
  );
  const CurrentUser = useSelector(
    (state) => state?.globalVariables?.loginUser?.employeeInfo
  );

  const nextStatusWithPermission = useMemo(() => {
    if (!Array.isArray(data?.nextStatus)) return [];

    return data.nextStatus.filter((status) => {
      const permissionIds = Array.isArray(status?.permissionIds)
        ? status.permissionIds
        : [];

      if (permissionIds?.length === 0) return true;
      if (permissionIds.includes(PROCESS_EXPENSE)) {
        setIsPaymentProcess(true);
      }
      return permissionIds.some((id) => userPermissions.includes(id));
    });
  }, [data, userPermissions]);

  const isCreatedBy = useMemo(() => {
    return data?.createdBy?.id === CurrentUser?.id;
  }, [data, CurrentUser]);

  const { mutate: MakeAction, isPending } = useActionOnPaymentRequest(() => {
    setClickedStatusId(null);
    reset();
  });

  const onSubmit = (formData) => {
    const Payload = {
      ...formData,
      paidAt: localToUtc(formData.paidAt),
      paymentRequestId: data.id,
      comment: formData.comment,
    };
    MakeAction(Payload);
  };

  if (isLoading) return <div>Lading..</div>;
  if (isError) return <Error error={error} />;
  const handleImageLoad = (id) => {
    setImageLoaded((prev) => ({ ...prev, [id]: true }));
  };
  const handleExpense = () => {
    setIsExpenseGenerate({ IsOpen: true, requestId: requestId });
    setVieRequest({ IsOpen: false, requestId: null });
  };

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

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

    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("billAttachments", 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) => {
    const newFiles = files.filter((_, i) => i !== index);
    setValue("billAttachments", newFiles, { shouldValidate: true });
  };
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {IsPaymentProcess && nextStatusWithPermission?.length > 0 && (
        <>
          {isProccesed ? (
            <div class="accordion-item active shadow-none">
              <h2 class="accordion-header d-flex align-items-center">
                <button
                  type="button"
                  class="accordion-button"
                  data-bs-toggle="collapse"
                  data-bs-target="#accordionWithIcon-1"
                  aria-expanded="true"
                >
                  <i class="icon-base bx bx-receipt me-2"></i>
                  Make Expense
                </button>
              </h2>

              <div
                id="accordionWithIcon-1"
                className="accordion-collapse collapse show"
              >
                <div className="row text-start mt-3">
                  {/* Expense Making */}
                  <div className="col-md-6 mb-2">
                    <Label
                      htmlFor="paymentModeId"
                      className="form-label"
                      required
                    >
                      Payment Mode
                    </Label>
                    <select
                      className="form-select form-select-sm"
                      id="paymentModeId"
                      {...register("paymentModeId")}
                    >
                      <option value="" disabled>
                        Select Mode
                      </option>
                      {PaymentModeLoading ? (
                        <option disabled>Loading...</option>
                      ) : (
                        PaymentModes?.map((payment) => (
                          <option key={payment.id} value={payment.id}>
                            {payment.name}
                          </option>
                        ))
                      )}
                    </select>
                    {errors.paymentModeId && (
                      <small className="danger-text">
                        {errors.paymentModeId.message}
                      </small>
                    )}
                  </div>

                  <div className="col-md-6">
                    <label htmlFor="statusId" className="form-label ">
                      GST Number
                    </label>
                    <input
                      type="text"
                      id="gstNumber"
                      className="form-control form-control-sm"
                      min="1"
                      {...register("gstNumber")}
                    />
                    {errors.gstNumber && (
                      <small className="danger-text">
                        {errors.gstNumber.message}
                      </small>
                    )}
                  </div>
                  <div className="col-12 col-md-6 text-start">
                    <label className="form-label">Location </label>
                    <input
                      type="text"
                      className="form-control form-control-sm"
                      {...register("location")}
                    />
                    {errors.location && (
                      <small className="danger-text">
                        {errors.location.message}
                      </small>
                    )}
                  </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"
                      style={{ cursor: "pointer" }}
                      onClick={() =>
                        document.getElementById("billAttachments").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, max 5MB)
                      </small>

                      <input
                        type="file"
                        id="billAttachments"
                        accept=".pdf,.jpg,.jpeg,.png"
                        multiple
                        style={{ display: "none" }}
                        {...register("billAttachments")}
                        onChange={(e) => {
                          onFileChange(e);
                          e.target.value = "";
                        }}
                      />
                    </div>
                    {errors.billAttachments && (
                      <small className="danger-text">
                        {errors.billAttachments.message}
                      </small>
                    )}
                    {files?.length > 0 && (
                      <Filelist
                        files={files}
                        removeFile={removeFile}
                        expenseToEdit={false}
                        sm={12}
                        md={12}
                      />
                    )}

                    {Array.isArray(errors.billAttachments) &&
                      errors.billAttachments.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>
              </div>
            </div>
          ) : (
            // Payment process
            <div className="row">
              <div className="col-12 col-md-6 text-start">
                <label className="form-label">Transaction Id </label>
                <input
                  type="text"
                  className="form-control form-control-sm"
                  {...register("paidTransactionId")}
                />
                {errors.paidTransactionId && (
                  <small className="danger-text">
                    {errors.paidTransactionId.message}
                  </small>
                )}
              </div>
              <div className="col-12 col-md-6 text-start mb-1">
                <label className="form-label">Transaction Date </label>
                <DatePicker
                  className="w-100"
                  name="paidAt"
                  control={control}
                  minDate={data?.createdAt}
                />
                {errors.paidAt && (
                  <small className="danger-text">{errors.paidAt.message}</small>
                )}
              </div>
              <div className="col-12  text-start mb-2">
                <label className="form-label">Paid By </label>
                <EmployeeSearchInput
                  control={control}
                  name="paidById"
                  placeholder="Enter Employee Name"
                  projectId={null}
                />
              </div>
              <div className="col-12 col-md-6 text-start mb-1">
                <Label className="form-label">TDS Percentage</Label>
                <input
                  type="number"
                  className="form-control form-control-sm"
                  {...register("tdsPercentage", { valueAsNumber: true })}
                  min="0"
                  step="any"
                />
                {errors.tdsPercentage && (
                  <small className="danger-text">
                    {errors.tdsPercentage.message}
                  </small>
                )}
              </div>
              <div className="col-12 col-md-6 text-start mb-1">
                <Label className="form-label" required>
                  Base Amount
                </Label>
                <input
                  type="number"
                  className="form-control form-control-sm"
                  {...register("baseAmount", { valueAsNumber: true })}
                  min="0"
                  step="any"
                />
                {errors.baseAmount && (
                  <small className="danger-text">
                    {errors.baseAmount.message}
                  </small>
                )}
              </div>
              <div className="col-12 col-md-6 text-start mb-1">
                <Label className="form-label" required>
                  Tax Amount
                </Label>
                <input
                  type="number"
                  className="form-control form-control-sm"
                  {...register("taxAmount", { valueAsNumber: true })}
                  min="0"
                  step="any"
                />
                {errors.taxAmount && (
                  <small className="danger-text">
                    {errors.taxAmount.message}
                  </small>
                )}
              </div>
            </div>
          )}
        </>
      )}
      <div className="col-12 mb-3 text-start">
        {((nextStatusWithPermission?.length > 0 && !isRejectedRequest) ||
          (isRejectedRequest && isCreatedBy)) && (
          <>
            <Label className="form-label me-2 mb-0" required>
              Comment
            </Label>
            <textarea
              className="form-control form-control-sm"
              {...register("comment")}
              rows="2"
            />
            {errors.comment && (
              <small className="danger-text">{errors.comment.message}</small>
            )}
          </>
        )}

        {nextStatusWithPermission?.length > 0 &&
          (!isRejectedRequest || isCreatedBy) && (
            <div className="text-end flex-wrap gap-2 my-2 mt-3">
              {nextStatusWithPermission?.map((status, index) => (
                <button
                  key={status.id || index}
                  type="button"
                  onClick={() => {
                    setClickedStatusId(status.id);
                    setValue("statusId", status.id);
                    handleSubmit(onSubmit)();
                  }}
                  disabled={isPending || isFetching}
                  className="btn btn-primary btn-sm cursor-pointer mx-2 border-0"
                >
                  {isPending && clickedStatusId === status.id
                    ? "Please Wait..."
                    : status.displayName || status.name}
                </button>
              ))}
            </div>
          )}
      </div>
    </form>
  );
};

export default ActionPaymentRequest;
