import { useCallback, useEffect, useState } from "react";

import { Form, Modal } from "antd";
import axios from "axios";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { toggleModalVisible } from "../../redux/modals/modals.actions";
import { selectTimeTicketTasks } from "../../redux/modals/modals.selectors";
import { selectCurrentUser } from "../../redux/user/user.selectors";
import TimeTicketTaskModalComponent from "./time-ticket-task-modal.component";
import { useApolloClient } from "@apollo/client/react";
import { QUERY_COMPLETED_TASKS } from "../../graphql/jobs.queries";
import "./time-ticket-task-modal.styles.scss";
import { selectTechnician } from "../../redux/tech/tech.selectors";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";

const mapStateToProps = createStructuredSelector({
  timeTicketTasksModal: selectTimeTicketTasks,
  currentUser: selectCurrentUser,
  technician: selectTechnician
});
const mapDispatchToProps = (dispatch) => ({
  toggleModalVisible: () => dispatch(toggleModalVisible("timeTicketTask"))
});
export default connect(mapStateToProps, mapDispatchToProps)(TimeTickeTaskModalContainer);

const toFiniteNumber = (value) => {
  const parsed = Number(value);
  return Number.isFinite(parsed) ? parsed : null;
};

const getPreviewPayoutAmount = (ticket) => {
  const productiveHours = toFiniteNumber(ticket?.productivehrs);
  const rate = toFiniteNumber(ticket?.rate);

  if (productiveHours === null || rate === null) {
    return null;
  }

  return productiveHours * rate;
};

export function TimeTickeTaskModalContainer({ currentUser, technician, timeTicketTasksModal, toggleModalVisible }) {
  const [form] = Form.useForm();
  const { context, open, actions } = timeTicketTasksModal;
  const [completedTasks, setCompletedTasks] = useState([]);
  const [unassignedHours, setUnassignedHours] = useState(0);
  const { t } = useTranslation();
  const [loading, setLoading] = useState(false);
  const client = useApolloClient();
  const notification = useNotification();

  async function handleFinish(values) {
    calculateTickets({ values, handleFinish: true });
  }

  const getCompletedTasks = useCallback(
    async (jobid) => {
      setLoading(true);

      const { data } = await client.query({
        query: QUERY_COMPLETED_TASKS,
        variables: { jobid }
      });

      setCompletedTasks(data.jobs_by_pk.completed_tasks || []);
      setLoading(false);
    },
    [client]
  );
  useEffect(() => {
    if (open) {
      form.setFieldsValue({ ...context, task: null, timetickets: null });
      if (context.jobid) {
        getCompletedTasks(context.jobid);
      }
    }
  }, [context.jobid, open, getCompletedTasks, form, context]);

  async function handleValueChange(changedValues, allValues) {
    if (changedValues.jobid) {
      getCompletedTasks(changedValues.jobid);
    }
    if (allValues.jobid && allValues.task) {
      calculateTickets({ values: allValues, handleFinish: false });
    }
  }

  const calculateTickets = async ({ values, handleFinish }) => {
    setLoading(true);
    try {
      const { data, ...response } = await axios.post("/payroll/claimtask", {
        jobid: values.jobid,
        task: values.task,
        calculateOnly: !handleFinish,
        employee: technician
          ? {
              name: `${technician.first_name} ${technician.last_name}`.trim(),
              employeeid: technician.id
            }
          : { name: currentUser.displayName, email: currentUser.email }
      });
      if (response.status === 200 && handleFinish) {
        //Close the modal
        if (actions?.refetch) actions.refetch();
        toggleModalVisible();
      } else if (handleFinish === false) {
        form.setFieldsValue({
          timetickets: (data.ticketsToInsert || []).map((ticket) => ({
            ...ticket,
            payoutamount: getPreviewPayoutAmount(ticket)
          }))
        });
        setUnassignedHours(data.unassignedHours);
      } else {
        notification.error({
          title: t("timetickets.errors.creating", {
            message: JSON.stringify(data)
          })
        });
      }
    } catch (error) {
      notification.error({
        title: t("timetickets.errors.creating", {
          message: error.response?.data?.error || error.message
        })
      });
    } finally {
      setLoading(false);
    }
  };

  return (
    <Modal
      destroyOnHidden
      open={open}
      onCancel={() => {
        toggleModalVisible();
        form.resetFields();
      }}
      width="80%"
      onOk={() => form.submit()}
    >
      <Form
        autoComplete={"off"}
        form={form}
        layout="vertical"
        onFinish={handleFinish}
        initialValues={context}
        onValuesChange={handleValueChange}
      >
        <TimeTicketTaskModalComponent
          form={form}
          loading={loading}
          completedTasks={completedTasks}
          unassignedHours={unassignedHours}
        />
      </Form>
    </Modal>
  );
}
