import { useCallback, useEffect, useRef, useState } from "react";
import AddTask from "./AddTask";
import { Button, Input, Select, Space, notification } from "antd";
import TaskTable from "./TaskTable";
import { useTeamData } from "../../Hooks/Teams";
import { StepForwardOutlined, StepBackwardOutlined } from "@ant-design/icons";
import { useTasks } from "../../Hooks/Tasks";
import { TTask } from "../../types/Tasks/TTasks";
import { admin_id, role, team_id } from "../../App";
//@ts-ignore
import addicon from "../../assets/addiconpng.png";
//@ts-ignore
import refreshicon from "../../assets/refreshIcon.png";
// @ts-ignore
import IconSearch from "../../assets/searchIcon.png";
import TaskModal from "./TaskModal";
import TaskUploadModal from "./TaskUploadModal";
import { NotificationPlacement } from "antd/es/notification/interface";
import { TCall } from "../../types/CallRequests/TCall";

const { Option } = Select;
const Task = () => {
  const [open, setOpen] = useState(false);
  const [modalOpen, setModalOpen] = useState(false);
  const [characters, setCharacters] = useState<TTask[] | undefined>();
  const [team, setTeam] = useState<any>();
  const [search, setSearch] = useState<string>("");
  const [status, setStatus] = useState<any>();
  const [page, setPage] = useState<any>(1);
  const [uploadOpen, setUploadOpen] = useState(false);

  let taskSocket: WebSocket;
  interface newData {
    callback_request: TCall;
    type: string;
    task: TTask;
  }

  const [isLive, setIslive] = useState(true);
  const [socketData, setSocketData] = useState<newData>();
  const connect = async () => {
    try {
      if (!taskSocket || taskSocket.readyState === WebSocket.CLOSED) {
        taskSocket = new WebSocket(
          `ws://10.10.10.45:8080/tasks/?user_id=${admin_id}`
        );
        // taskSocket = new WebSocket(
        //   `wss://api.tteld.co/tasks/?user_id=${admin_id}`
        // );

        taskSocket.addEventListener("open", (event) => {
          console.log("open");
          setIslive(true);
        });
        taskSocket.addEventListener("message", (event) => {
          const newData: newData = JSON.parse(event.data);
          setSocketData(newData);
        });
        taskSocket.addEventListener("error", (errorEvent) => {
          console.error("WebSocket error:", errorEvent);
        });

        taskSocket.addEventListener("close", (event) => {
          setIslive(false);
          console.log("close");
        });
      }
    } catch (err) {}
  };

  useEffect(() => {
    connect();
  });

  const [api, contextHolder] = notification.useNotification();
  const openNotification = useCallback(
    (placement: NotificationPlacement, data: TCall) => {
      console.log(data);

      api.info({
        message: `Driver ${data?.driver?.name} from ${data?.company?.name} company has made a call request`,
        placement,
      });
    },
    [api]
  );

  useEffect(() => {
    if (
      socketData &&
      ((role !== "Checker" &&
        (!team || team.includes(socketData?.task?.assigned_to?.id))) ||
        role === "Checker") &&
      (!status || status.includes(socketData.task.status))
    ) {
      setCharacters((prev: TTask[] | undefined) => {
        if (prev && prev?.length >= 15) {
          prev?.pop();
        }
        if (socketData.type === "task_create") {
          return [socketData.task, ...(prev || [])];
        } else if (socketData.type === "task_update") {
          if (role !== "Checker") {
            const updatedData =
              prev?.filter((b: TTask) => b.id !== socketData.task.id) || [];
            const data: TTask[] = [socketData.task, ...updatedData];
            data.sort((a: TTask, b: TTask) => {
              if (a.status === "New" && b.status === "New") {
                return 0;
              }
              if (a.status === "New") {
                return -1;
              }
              if (b.status === "New") {
                return 1;
              }
              return 0;
            });
            return data;
          } else {
            const data = (prev || []).map((b: TTask) =>
              b.id === socketData.task.id ? socketData.task : b
            );
            return data;
          }
        } else if (socketData.type === "task_delete") {
          const data = (prev || []).filter(
            (b: TTask) => b.id !== socketData.task.id
          );
          return data;
        } else if (socketData.type === "task_forward") {
          if (role === "Checker") {
            if (socketData.task.assigned_to.id === team_id) {
              return [socketData.task, ...(prev || [])];
            } else {
              const data = (prev || []).filter(
                (b: TTask) => b.id !== socketData.task.id
              );
              return data;
            }
          } else {
            const updatedData =
              prev?.filter((b: TTask) => b.id !== socketData.task.id) || [];
            const data: TTask[] = [socketData.task, ...updatedData];
            data.sort((a: TTask, b: TTask) => {
              if (a.status === "New" && b.status === "New") {
                return 0;
              }
              if (a.status === "New") {
                return -1;
              }
              if (b.status === "New") {
                return 1;
              }
              return 0;
            });
            return data;
          }
        } else if (socketData.type === "callback_request") {
          if (socketData?.callback_request) {
            console.log("run");

            openNotification("bottomRight", socketData?.callback_request);
          }
        }
        return prev;
      });
    }
  }, [socketData, openNotification]);

  const teamData = useTeamData("");

  const teamOptions: { label: string; value: any }[] | undefined =
    teamData?.data?.map((item) => ({
      label: item?.name,
      value: item?.id,
    }));

  const { data, isLoading, refetch } = useTasks({
    search,
    status,
    team,
    page,
  });
  useEffect(() => {
    if (data) {
      setCharacters(data?.data);
    }
  }, [data]);

  useEffect(() => {
    setPage(1);
  }, [search, status, team]);

  const showModal = () => {
    setOpen(true);
  };
  const [recordTask, setRecordTask] = useState<TTask>();
  const showTaskModal = (e: TTask) => {
    setRecordTask(e);
    setModalOpen(true);
  };

  const Next = () => {
    const a = Number(page) + 1;
    setPage(a);
  };
  const Previos = () => {
    Number(page);
    if (page > 1) {
      const a = Number(page) - 1;
      setPage(a);
    }
  };

  const timerRef = useRef<NodeJS.Timeout | null>(null);
  const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (timerRef.current) {
      clearTimeout(timerRef.current);
    }

    const searchText = e.target.value;
    timerRef.current = setTimeout(() => {
      setSearch(searchText);
    }, 1000);
  };
  const theme = localStorage.getItem("theme") === "true" ? true : false;
  return (
    <div>
      {contextHolder}
      {open && <AddTask open={open} setOpen={setOpen} />}
      {uploadOpen && (
        <TaskUploadModal
          refetch={refetch}
          recordTask={recordTask}
          uploadOpen={uploadOpen}
          setUploadOpen={setUploadOpen}
        />
      )}
      {modalOpen && (
        <TaskModal
          uploadOpen={uploadOpen}
          setUploadOpen={setUploadOpen}
          recordTask={recordTask}
          modalOpen={modalOpen}
          setModalOpen={setModalOpen}
          refetch={refetch}
        />
      )}
      <div className="header d-flex">
        <div className="header-title d-flex">
          <p className="title">Tasks</p>
          {isLive ? (
            <div className="d-flex" style={{ marginRight: 15 }}>
              <div className="circle"></div>
              <p className={!theme ? "live-p" : "live-p-dark"}>online</p>
            </div>
          ) : (
            <div className="d-flex" style={{ marginRight: 15 }}>
              <div className="circle2"></div>
              <p className="live-p">offline</p>
            </div>
          )}
        </div>
        <div className="d-flex">
          {role !== "Checker" && (
            <button className="btn-add d-flex" onClick={showModal}>
              <img style={{ marginRight: 8 }} src={addicon} alt="" />
              Add Task
            </button>
          )}
          <button
            className={`btn-refresh-${theme && "dark"} d-flex`}
            onClick={() => {
              refetch();
              connect();
            }}
          >
            <img style={{ marginRight: 8 }} src={refreshicon} alt="" />
            Refresh
          </button>
        </div>
      </div>
      <div className="filter d-flex">
        <div className="search-div">
          <img src={IconSearch} alt="" />
          <input
            className={`search-input-${theme}`}
            type="text"
            placeholder="Search"
            onChange={handleSearchChange}
          />
        </div>
        <Select
          style={{ width: 260, marginLeft: 12 }}
          placeholder="status"
          onChange={(value: any) => setStatus(value)}
          mode="multiple"
        >
          <Option value="New">New</Option>
          <Option value="Checking">Checking</Option>
          <Option value="Done">Done</Option>
        </Select>
        {role !== "Checker" && (
          <Select
            mode="multiple"
            style={{ width: 260, marginLeft: 12 }}
            placeholder="team"
            onChange={(value: any) => setTeam(value)}
            options={teamOptions}
          />
        )}
      </div>
      <TaskTable
        data={{ characters }}
        isLoading={isLoading}
        showTaskModal={showTaskModal}
      />
      <Space style={{ width: "100%", marginTop: 10 }} direction="vertical">
        <Space style={{ width: "100%", justifyContent: "flex-end" }} wrap>
          <Button
            type="primary"
            icon={<StepBackwardOutlined />}
            onClick={Previos}
          ></Button>
          <Input
            style={{ width: 50, textAlign: "right" }}
            value={page}
            onChange={(e) => {
              let num = e.target.value;
              if (Number(num) && num !== "0") {
                setPage(num);
              }
            }}
          />
          <Button
            type="primary"
            icon={<StepForwardOutlined />}
            onClick={Next}
          ></Button>
        </Space>
      </Space>
    </div>
  );
};

export default Task;