import { Button, Card, Col, Row, Select, Space } from "antd";
import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { useLocation, useNavigate } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import SocketIO from "socket.io-client";
import DmsAllocationsSummaryApComponent from "../../components/dms-allocations-summary-ap/dms-allocations-summary-ap.component";
import DmsLogEvents from "../../components/dms-log-events/dms-log-events.component";
import { auth } from "../../firebase/firebase.utils";
import { setBreadcrumbs, setSelectedHeader } from "../../redux/application/application.actions";
import InstanceRenderManager from "../../utils/instanceRenderMgr";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";

const mapStateToProps = createStructuredSelector({});

const mapDispatchToProps = (dispatch) => ({
  setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)),
  setSelectedHeader: (key) => dispatch(setSelectedHeader(key))
});

export default connect(mapStateToProps, mapDispatchToProps)(DmsContainer);

export const socket = SocketIO(import.meta.env.PROD ? import.meta.env.VITE_APP_AXIOS_BASE_API_URL : "", {
  path: "/ws",
  withCredentials: true,
  auth: async (callback) => {
    const token = auth.currentUser && (await auth.currentUser.getIdToken());
    callback({ token });
  }
});

export function DmsContainer({ setBreadcrumbs, setSelectedHeader }) {
  const { t } = useTranslation();
  const [logLevel, setLogLevel] = useState("DEBUG");
  const history = useNavigate();
  const [logs, setLogs] = useState([]);
  const notification = useNotification();

  const { state } = useLocation();

  const logsRef = useRef(null);

  useEffect(() => {
    document.title = t("titles.dms", {
      app: InstanceRenderManager({
        imex: "$t(titles.imexonline)",
        rome: "$t(titles.romeonline)"
      })
    });
    setSelectedHeader("dms");
    setBreadcrumbs([
      {
        link: "/manage/accounting/payables",
        label: t("titles.bc.accounting-payables")
      },
      {
        link: "/manage/dms",
        label: t("titles.bc.dms")
      }
    ]);
  }, [t, setBreadcrumbs, setSelectedHeader]);

  useEffect(() => {
    socket.on("connect", () => socket.emit("set-log-level", logLevel));
    socket.on("reconnect", () => {
      setLogs((logs) => {
        return [
          ...logs,
          {
            timestamp: new Date(),
            level: "WARN",
            message: "Reconnected to CDK Export Service"
          }
        ];
      });
    });

    socket.on("log-event", (payload) => {
      setLogs((logs) => {
        return [...logs, payload];
      });
    });

    socket.on("ap-export-complete", () => {
      notification.success({
        title: t("jobs.labels.dms.apexported")
      });
    });

    if (socket.disconnected) socket.connect();

    return () => {
      socket.removeAllListeners();
      socket.disconnect();
    };
  }, []);

  if (!state?.billids) {
    history(`/manage/accounting/payables`);
  }

  return (
    <Row gutter={[16, 16]}>
      <Col md={24} lg={12}>
        <DmsAllocationsSummaryApComponent socket={socket} billids={state?.billids} />
      </Col>

      <Col md={24} lg={12}>
        <div ref={logsRef}>
          <Card
            title={t("jobs.labels.dms.logs")}
            extra={
              <Space wrap>
                <Select
                  placeholder="Log Level"
                  value={logLevel}
                  onChange={(value) => {
                    setLogLevel(value);
                    socket.emit("set-log-level", value);
                  }}
                  options={[
                    { key: "DEBUG", value: "DEBUG", label: "DEBUG" },
                    { key: "INFO", value: "INFO", label: "INFO" },
                    { key: "WARN", value: "WARN", label: "WARN" },
                    { key: "ERROR", value: "ERROR", label: "ERROR" }
                  ]}
                />
                <Button onClick={() => setLogs([])}>Clear Logs</Button>
                <Button
                  onClick={() => {
                    setLogs([]);

                    socket.disconnect();
                    socket.connect();
                  }}
                >
                  Reconnect
                </Button>
              </Space>
            }
          >
            <DmsLogEvents logs={logs} />
          </Card>
        </div>
      </Col>
    </Row>
  );
}
