import React, { useState, useEffect, useRef, useCallback } from "react";
import { useDispatch, useSelector } from "react-redux";
import { changeMaster } from "../../slices/localVariablesSlice";
import useMaster, { useServices } from "../../hooks/masterHook/useMaster";
import { useForm, Controller } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useSelectedProject } from "../../slices/apiDataManager";
import { useEmployeesAllOrByProjectId } from "../../hooks/useEmployees";
import { TasksRepository } from "../../repositories/ProjectRepository";
import showToast from "../../services/toastService";
import {
  useEmployeeForTaskAssign,
  useProjectAssignedOrganizationsName,
  useProjectAssignedServices,
  useProjectDetails,
} from "../../hooks/useProjects";
import eventBus from "../../services/eventBus";
import { useCreateTask } from "../../hooks/useTasks";
import Label from "../common/Label";
import { AppFormController } from "../../hooks/appHooks/useAppForm";
import SelectField from "../common/Forms/SelectField";

const TaskSchema = (maxPlanned) => {
  return z.object({
    selectedEmployees: z
      .array(z.string())
      .min(1, { message: "At least one employee must be selected" }),
    description: z.string().min(1, { message: "Description is required" }),
    plannedTask: z.preprocess(
      (val) => parseInt(val, 10),
      z
        .number({
          required_error: "Planned task is required",
          invalid_type_error: "Target for Today must be a number",
        })
        .int()
        .positive({ message: "Planned task must be a positive number" })
        .max(maxPlanned, {
          message: `Planned task cannot exceed ${maxPlanned}`,
        })
    ),
  });
};

const AssignTask = ({ assignData, onClose, setAssigned }) => {
  const planned = assignData?.workItem?.plannedWork || 0;
  const completed = assignData?.workItem?.completedWork || 0;
  const maxPlanned = planned - completed;

  const [isHelpVisibleTarget, setIsHelpVisibleTarget] = useState(false);
  const helpPopupRefTarget = useRef(null);
  const [isHelpVisible, setIsHelpVisible] = useState(false);
  const [selectedService, setSelectedService] = useState(null);
  const [selectedOrganization, setSelectedOrganization] = useState(null);

  const { mutate: assignTask, isPending: isSubmitting } = useCreateTask({
    onSuccessCallback: closedModel,
  });

  const dropdownRef = useRef(null);
  const [open, setOpen] = useState(false);

  useEffect(() => {
    const handleClickOutside = (event) => {
      if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
        setOpen(false);
      }
    };
    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, []);

  const infoRef = useRef(null);
  const infoRef1 = useRef(null);
  const [searchTerm, setSearchTerm] = useState("");

  useEffect(() => {
    if (typeof bootstrap !== "undefined") {
      infoRef.current &&
        new bootstrap.Popover(infoRef.current, {
          trigger: "focus",
          placement: "right",
          html: true,
          content: `<div>Total Pending tasks of the Activity</div>`,
        });

      infoRef1.current &&
        new bootstrap.Popover(infoRef1.current, {
          trigger: "focus",
          placement: "right",
          html: true,
          content: `<div>Target task for today</div>`,
        });
    } else {
      console.warn("Bootstrap is not available. Popovers might not function.");
    }
  }, []);

  const selectedProject = useSelectedProject();
  const { data: serviceList, isLoading: isServiceLoading } = useProjectAssignedServices(selectedProject);
  const { data: organizationList, isLoading: isOrgLoading } =
    useProjectAssignedOrganizationsName(selectedProject);
  const { data: employees, isLoading: isEmployeeLoading } =
    useEmployeeForTaskAssign(
      selectedProject,
      selectedService,
      selectedOrganization
    );

  const dispatch = useDispatch();
  const { loading, data: jobRoleData } = useMaster("Job Role");

  const [selectedRoles, setSelectedRoles] = useState(["all"]);
  const [displayedSelection, setDisplayedSelection] = useState("");

  const {
    handleSubmit,
    control,
    setValue,
    watch,
    formState: { errors },
    reset,
    trigger,
  } = useForm({
    defaultValues: { selectedEmployees: [], description: "", plannedTask: "" },
    resolver: zodResolver(TaskSchema(maxPlanned)),
  });

  const handleCheckboxChange = (event, user) => {
    const updatedSelectedEmployees = event.target.checked
      ? [...(watch("selectedEmployees") || []), user.id].filter(
        (v, i, a) => a.indexOf(v) === i
      )
      : (watch("selectedEmployees") || []).filter((id) => id !== user.id);

    setValue("selectedEmployees", updatedSelectedEmployees);
    trigger("selectedEmployees");
  };

  useEffect(() => {
    dispatch(changeMaster("Job Role"));
    setSelectedRoles(["all"]);
  }, [dispatch]);

  const handleRoleChange = (event, roleId) => {
    setSelectedRoles((prev) => {
      if (roleId === "all") return ["all"];
      const newRoles = prev.filter((r) => r !== "all");
      return newRoles.includes(roleId)
        ? newRoles.filter((r) => r !== roleId)
        : [...newRoles, roleId];
    });
  };

  useEffect(() => {
    if (selectedRoles.includes("all")) {
      setDisplayedSelection("All Roles");
    } else if (selectedRoles.length > 0) {
      setDisplayedSelection(
        selectedRoles
          .map((id) => jobRoleData?.find((r) => String(r.id) === id)?.name)
          .filter(Boolean)
          .join(", ")
      );
    } else setDisplayedSelection("Select Roles");
  }, [selectedRoles, jobRoleData]);

  const handleSearchChange = (e) => setSearchTerm(e.target.value);

  const filteredEmployees = employees?.data?.filter((emp) => {
    const matchesRole =
      selectedRoles.includes("all") ||
      selectedRoles.includes(String(emp.jobRoleId));
    const searchLower = searchTerm.toLowerCase();
    const fullName = `${emp.firstName} ${emp.lastName}`.toLowerCase();
    const jobRoleName =
      jobRoleData
        ?.find((role) => role.id === emp.jobRoleId)
        ?.name?.toLowerCase() || "";
    return (
      matchesRole &&
      (fullName.includes(searchLower) || jobRoleName.includes(searchLower))
    );
  });

  const jobRolesForDropdown = jobRoleData?.filter((role) =>
    new Set(employees?.data?.map((emp) => emp.jobRoleId).filter(Boolean)).has(
      role.id
    )
  );

  const selectedRolesCount = selectedRoles.includes("all")
    ? 0
    : selectedRoles.length;

  const onSubmit = (data) => {
    assignTask({
      payload: {
        taskTeam: data.selectedEmployees.filter(Boolean),
        plannedTask: data.plannedTask,
        description: data.description,
        assignmentDate: new Date().toISOString(),
        workItemId: assignData?.workItem.id,
      },
      workAreaId: assignData?.workArea?.id,
    });
  };

  function closedModel() {
    reset();
    onClose();
  }

  return (
    <div className="fs-5 text-dark text-center d-flex align-items-center justify-content-center flex-wrap">
      <p className="align-items-center flex-wrap m-0">Assign Task</p>
      <div className="container my-3">
        <div className="mb-1">
          <p className="mb-0">
            <span className="text-dark text-start d-flex align-items-center flex-wrap form-text">
              <span className="me-2 m-0 font-bold">Work Location :</span>
              {[
                assignData?.building?.buildingName,
                assignData?.floor?.floorName,
                assignData?.workArea?.areaName,
                assignData?.workItem?.activityMaster?.activityName,
              ]
                .filter(Boolean)
                .map((item, index, array) => (
                  <span key={index} className="d-flex align-items-center">
                    {item}
                    {index < array.length - 1 && (
                      <i className="bx bx-chevron-right mx-2"></i>
                    )}
                  </span>
                ))}
            </span>
          </p>

          <form onSubmit={handleSubmit(onSubmit)}>
            <div className="form-label text-start">
              <div className="row mb-1">
                <div className="col-12">
                  <div className="row text-start">
                    <div className="col-12 col-md-8 d-flex flex-row gap-3 align-items-center mt-4">
                      <div>
                        <AppFormController
                          name="organizationId"
                          control={control}
                          rules={{ required: "Organization is required" }}
                          render={({ field }) => (
                            <SelectField
                              label="" // No label here, use external label if needed
                              options={organizationList ?? []}
                              placeholder="--Select Organization--"
                              required
                              labelKey="name"
                              valueKeyKey="id"
                              value={field.value || ""}
                              onChange={field.onChange}
                              isLoading={isServiceLoading}
                              className="m-0 form-select-sm w-100"
                            />
                          )}
                        />

                        {errors.organizationId && (
                          <small className="danger-text">{errors.organizationId.message}</small>
                        )}
                      </div>

                      <div>
                        <AppFormController
                          name="serviceId"
                          control={control}
                          rules={{ required: "Service is required" }}
                          render={({ field }) => (
                            <SelectField
                              label="" // No label as you have one above or elsewhere
                              options={serviceList ?? []}
                              placeholder="--Select Service--"
                              required
                              labelKey="name"
                              valueKeyKey="id"
                              value={field.value || ""}
                              onChange={field.onChange}
                              isLoading={isOrgLoading}
                              className="m-0 form-select-sm w-100"
                            />
                          )}
                        />

                        {errors.serviceId && (
                          <small className="danger-text">{errors.serviceId.message}</small>
                        )}
                      </div>
                    </div>
                    <div
                      className="col-12 col-md-4 d-flex flex-row gap-3 align-items-center justify-content-end"
                      ref={dropdownRef}
                    >
                      {/* Dropdown */}
                      <div className="dropdown position-relative d-inline-block">
                        <a
                          className={`dropdown-toggle hide-arrow cursor-pointer ${selectedRoles.includes("all") ||
                            selectedRoles.length === 0
                            ? "text-secondary"
                            : "text-primary"
                            }`}
                          onClick={() => setOpen(!open)}
                        >
                          <i className="bx bx-slider-alt ms-2"></i>
                        </a>

                        {/* Badge */}
                        {selectedRolesCount > 0 && (
                          <span
                            className="position-absolute top-0 start-100 translate-middle badge rounded-circle bg-warning text-white text-tiny"
                            style={{
                              fontSize: "0.65rem",
                              minWidth: "18px",
                              height: "18px",
                              padding: "0",
                              lineHeight: "18px",
                              textAlign: "center",
                              zIndex: 10,
                            }}
                          >
                            {selectedRolesCount}
                          </span>
                        )}

                        {/* Dropdown Menu */}
                        {open && (
                          <ul
                            className="dropdown-menu show p-2 text-capitalize"
                            style={{ maxHeight: "300px", overflowY: "auto" }}
                          >
                            {/* All Roles */}
                            <li key="all">
                              <div className="form-check dropdown-item py-0">
                                <input
                                  className="form-check-input"
                                  type="checkbox"
                                  id="checkboxAllRoles"
                                  value="all"
                                  checked={selectedRoles.includes("all")}
                                  onChange={(e) =>
                                    handleRoleChange(e, e.target.value)
                                  }
                                />
                                <label
                                  className="form-check-label ms-2"
                                  htmlFor="checkboxAllRoles"
                                >
                                  All Roles
                                </label>
                              </div>
                            </li>

                            {/* Dynamic Roles */}
                            {jobRolesForDropdown?.map((role) => (
                              <li key={role.id}>
                                <div className="form-check dropdown-item py-0">
                                  <input
                                    className="form-check-input"
                                    type="checkbox"
                                    id={`checkboxRole-${role.id}`}
                                    value={role.id}
                                    checked={selectedRoles.includes(
                                      String(role.id)
                                    )}
                                    onChange={(e) =>
                                      handleRoleChange(e, e.target.value)
                                    }
                                  />
                                  <label
                                    className="form-check-label ms-2"
                                    htmlFor={`checkboxRole-${role.id}`}
                                  >
                                    {role.name}
                                  </label>
                                </div>
                              </li>
                            ))}
                          </ul>
                        )}
                      </div>

                      {/* Search Box */}
                      <div>
                        <input
                          type="text"
                          className="form-control form-control-sm ms-auto mb-2 mt-2"
                          placeholder="Search employees or roles..."
                          value={searchTerm}
                          onChange={handleSearchChange}
                        />
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              {/* Employees list */}
              <div
                className="col-12 mt-2"
                style={{
                  maxHeight: "280px",
                  overflowY: "auto",
                  overflowX: "hidden",
                }}
              >
                {selectedRoles?.length > 0 && (
                  <div className="row">
                    {isEmployeeLoading ? (
                      <div className="col-12">
                        <p className="text-center">Loading employees...</p>
                      </div>
                    ) : filteredEmployees?.length > 0 ? (
                      filteredEmployees.map((emp, index) => {
                        const jobRole = jobRoleData?.find(
                          (role) => role?.id === emp?.jobRoleId
                        );

                        return (
                          <div
                            key={`${emp.index}-${index}`}
                            className="col-6 col-md-4 col-lg-3 mb-3"
                          >
                            <div className="form-check d-flex align-items-start">
                              <Controller
                                name="selectedEmployees"
                                control={control}
                                render={({ field }) => (
                                  <input
                                    {...field}
                                    className="form-check-input me-1 mt-1"
                                    type="checkbox"
                                    id={`employee-${emp?.id}`}
                                    value={emp.id}
                                    checked={field.value?.includes(emp.id)}
                                    onChange={(e) => {
                                      handleCheckboxChange(e, emp);
                                    }}
                                  />
                                )}
                              />
                              <div className="flex-grow-1">
                                <p
                                  className="mb-0"
                                  style={{ fontSize: "13px" }}
                                >
                                  {emp.firstName} {emp.lastName}
                                </p>
                                <small
                                  className="text-muted"
                                  style={{ fontSize: "11px" }}
                                >
                                  {loading ? (
                                    <span className="placeholder-glow">
                                      <span className="placeholder col-6"></span>
                                    </span>
                                  ) : (
                                    jobRole?.name || "Unknown Role"
                                  )}
                                </small>
                              </div>
                            </div>
                          </div>
                        );
                      })
                    ) : (
                      <div className="col-12">
                        <p className="text-center">
                          No employees found for the selected filter.
                        </p>
                      </div>
                    )}
                  </div>
                )}
              </div>

              <div
                className="col-12 h-25 overflow-auto"
                style={{ maxHeight: "200px" }}
              >
                {watch("selectedEmployees")?.length > 0 && (
                  <div className="mt-1">
                    <div className="text-start px-2">
                      {watch("selectedEmployees")?.map((empId, ind) => {
                        const emp = employees?.data?.find(
                          (emp) => emp.id === empId
                        );
                        return (
                          emp && (
                            <span
                              key={`${empId}-${ind}`}
                              className="badge rounded-pill bg-label-primary d-inline-flex align-items-center me-1 mb-1"
                            >
                              {emp.firstName} {emp.lastName}
                              <p
                                type="button"
                                className=" btn-close-white p-0 m-0"
                                aria-label="Close"
                                onClick={() => {
                                  const updatedSelected = watch(
                                    "selectedEmployees"
                                  ).filter((id) => id !== empId);
                                  setValue(
                                    "selectedEmployees",
                                    updatedSelected
                                  );
                                  trigger("selectedEmployees");
                                }}
                              >
                                <i className="icon-base bx bx-x icon-md "></i>
                              </p>
                            </span>
                          )
                        );
                      })}
                    </div>
                  </div>
                )}
              </div>

              {!loading && errors.selectedEmployees && (
                <div className="danger-text mt-1">
                  <p>{errors.selectedEmployees.message}</p>{" "}
                </div>
              )}

              <div className="col-md text-start mx-0 px-0">
                <div className="form-check form-check-inline mt-3 px-1">
                  <label className="form-text text-dark align-items-center d-flex">
                    Pending Task of Activity :
                    <label className="form-check-label fs-7 ms-4">
                      <strong>
                        {assignData?.workItem?.plannedWork -
                          assignData?.workItem?.completedWork}
                      </strong>{" "}
                      <u>
                        {
                          assignData?.workItem?.activityMaster
                            ?.unitOfMeasurement
                        }
                      </u>
                    </label>
                  </label>
                </div>
              </div>

              {/* Target for Today input and validation */}
              <div className="col-md text-start mx-0 px-0">
                <div className="form-check form-check-inline mt-2 px-1 mb-2 text-start">
                  <label className="text-dark d-flex align-items-center flex-wrap form-text">
                    <Label htmlFor="targetToday" required className="me-1">
                      Target for Today
                    </Label>

                    <span style={{ marginLeft: "37px" }}>:</span>
                  </label>
                </div>
                <div
                  className="form-check form-check-inline col-sm-3 mt-2"
                  style={{ marginLeft: "-28px" }}
                >
                  <Controller
                    name="plannedTask"
                    control={control}
                    render={({ field }) => (
                      <div className="d-flex align-items-center gap-1 ">
                        <input
                          type="text"
                          className="form-control form-control-sm"
                          {...field}
                        />
                        <span
                          style={{ paddingLeft: "6px", whiteSpace: "nowrap" }}
                        >
                          <u>
                            {
                              assignData?.workItem?.activityMaster
                                ?.unitOfMeasurement
                            }
                          </u>
                        </span>
                      </div>
                    )}
                  />
                </div>

                {errors.plannedTask && (
                  <div className="danger-text mt-1">
                    {errors.plannedTask.message}
                  </div>
                )}
              </div>
              <Label
                className="form-text fs-7 m-1 text-lg text-dark"
                htmlFor="descriptionTextarea"
                required
              >
                Description
              </Label>
              <Controller
                name="description"
                control={control}
                render={({ field }) => (
                  <textarea {...field} className="form-control" rows="2" />
                )}
              />
              {errors.description && (
                <div className="danger-text">{errors.description.message}</div>
              )}
            </div>

            {/* Submit and Cancel buttons */}
            <div className="col-12 d-flex justify-content-end align-items-center gap-2 mt-6">
              <button
                type="reset"
                className="btn btn-sm btn-label-secondary"
                data-bs-dismiss="modal"
                aria-label="Close"
                onClick={closedModel}
                disabled={isSubmitting || loading}
              >
                Cancel
              </button>
              <button
                type="submit"
                className="btn btn-sm btn-primary"
                disabled={isSubmitting || loading}
              >
                {isSubmitting ? "Please Wait" : "Submit"}
              </button>
            </div>
          </form>
        </div>
      </div>
    </div>
  );
};

export default AssignTask;
