import React, { useCallback, useEffect, useState } from "react";
import day from "../../utils/day";
import axios from "axios";
import { Badge, Card, Space, Table, Tag } from "antd";
import { gql, useQuery } from "@apollo/client";
import { DateTimeFormatterFunction } from "../../utils/DateFormatter";
import { isEmpty } from "lodash";
import { useTranslation } from "react-i18next";

import "./job-lifecycle.styles.scss";

// show text on bar if text can fit
export function JobLifecycleComponent({ job, statuses, ...rest }) {
  const [loading, setLoading] = useState(true);
  const [lifecycleData, setLifecycleData] = useState(null);
  const { t } = useTranslation(); // Used for tracking external state changes.

  const { data } = useQuery(
    gql`
      query get_job_test($id: uuid!) {
        jobs_by_pk(id: $id) {
          id
          status
        }
      }
    `,
    {
      variables: {
        id: job.id
      },
      fetchPolicy: "cache-only"
    }
  );

  /**
   * Gets the lifecycle data for the job.
   * @returns {Promise<void>}
   */
  const getLifecycleData = useCallback(async () => {
    if (job && job.id && statuses && statuses.statuses) {
      try {
        setLoading(true);
        const response = await axios.post("/job/lifecycle", {
          jobids: job.id,
          statuses: statuses.statuses
        });
        const data = response.data.transition[job.id];
        setLifecycleData(data);
      } catch (err) {
        console.error(`${t("job_lifecycle.errors.fetch")}: ${err.message}`);
      } finally {
        setLoading(false);
      }
    }
  }, [job, statuses, t]);

  useEffect(() => {
    if (!data) return;
    setTimeout(() => {
      getLifecycleData().catch((err) => console.error(`${t("job_lifecycle.errors.fetch")}: ${err.message}`));
    }, 500);
  }, [data, getLifecycleData, t]);

  const columns = [
    {
      title: t("job_lifecycle.columns.value"),
      dataIndex: "value",
      key: "value"
    },
    {
      title: t("job_lifecycle.columns.start"),
      dataIndex: "start",
      key: "start",
      render: (text) => DateTimeFormatterFunction(text),
      sorter: (a, b) => day(a.start).unix() - day(b.start).unix()
    },
    {
      title: t("job_lifecycle.columns.relative_start"),
      dataIndex: "start_readable",
      key: "start_readable"
    },
    {
      title: t("job_lifecycle.columns.end"),
      dataIndex: "end",
      key: "end",
      sorter: (a, b) => {
        if (isEmpty(a.end) || isEmpty(b.end)) {
          if (isEmpty(a.end) && isEmpty(b.end)) {
            return 0;
          }
          return isEmpty(a.end) ? 1 : -1;
        }
        return day(a.end).unix() - day(b.end).unix();
      },
      render: (text) => (isEmpty(text) ? t("job_lifecycle.content.not_available") : DateTimeFormatterFunction(text))
    },
    {
      title: t("job_lifecycle.columns.relative_end"),
      dataIndex: "end_readable",
      key: "end_readable"
    },
    {
      title: t("job_lifecycle.columns.duration"),
      dataIndex: "duration_readable",
      key: "duration_readable",
      sorter: (a, b) => a.duration - b.duration
    }
  ];

  return (
    <Card loading={loading} title={t("job_lifecycle.content.title")}>
      {!loading ? (
        lifecycleData && lifecycleData.lifecycle && lifecycleData.durations ? (
          <Space direction="vertical" style={{ width: "100%" }}>
            <Card
              type="inner"
              title={
                <Space direction="horizontal" size="small">
                  <Badge status="processing" count={lifecycleData.durations.totalStatuses} />
                  {t("job_lifecycle.content.title_durations")}
                </Space>
              }
              style={{ width: "100%" }}
            >
              <div
                id="bar-container"
                style={{
                  display: "flex",
                  width: "100%",
                  height: "100px",
                  textAlign: "center",
                  borderRadius: "5px",
                  borderWidth: "5px",
                  borderStyle: "solid",
                  borderColor: "#f0f2f5",
                  margin: 0,
                  padding: 0
                }}
              >
                {lifecycleData.durations.summations.map((key, index, array) => {
                  const isFirst = index === 0;
                  const isLast = index === array.length - 1;
                  return (
                    <div
                      key={key.status}
                      style={{
                        overflow: "hidden",
                        display: "flex",
                        flexDirection: "column",
                        justifyContent: "center",
                        alignItems: "center",
                        margin: 0,
                        padding: 0,

                        borderTop: "1px solid #f0f2f5",
                        borderBottom: "1px solid #f0f2f5",
                        borderLeft: isFirst ? "1px solid #f0f2f5" : undefined,
                        borderRight: isLast ? "1px solid #f0f2f5" : undefined,

                        backgroundColor: key.color,
                        width: `${key.percentage}%`
                      }}
                      aria-label={`${key.status} | ${key.roundedPercentage} | ${key.humanReadable}`}
                      title={`${key.status} | ${key.roundedPercentage} | ${key.humanReadable}`}
                    >
                      {key.percentage > 15 ? (
                        <>
                          <div>{key.roundedPercentage}</div>
                          <div
                            style={{
                              backgroundColor: "#f0f2f5",
                              borderRadius: "5px",
                              paddingRight: "2px",
                              paddingLeft: "2px",
                              fontSize: "0.8rem"
                            }}
                          >
                            {key.status}
                          </div>
                        </>
                      ) : null}
                    </div>
                  );
                })}
              </div>
              <Card type="inner" title={t("job_lifecycle.content.legend_title")} style={{ marginTop: "10px" }}>
                <div>
                  {lifecycleData.durations.summations.map((key) => (
                    <Tag key={key.status} color={key.color} style={{ width: "13vh", padding: "4px", margin: "4px" }}>
                      <div
                        aria-label={`${key.status} | ${key.roundedPercentage} | ${key.humanReadable}`}
                        title={`${key.status} | ${key.roundedPercentage} | ${key.humanReadable}`}
                        style={{
                          backgroundColor: "#f0f2f5",
                          color: "#000",
                          padding: "4px",
                          textAlign: "center"
                        }}
                      >
                        {key.status} ({key.roundedPercentage})
                      </div>
                    </Tag>
                  ))}
                </div>
              </Card>
              {lifecycleData?.durations?.humanReadableTotal ||
              (lifecycleData.lifecycle[0] &&
                lifecycleData.lifecycle[0].value &&
                lifecycleData?.durations?.totalCurrentStatusDuration?.humanReadable) ? (
                <Card style={{ marginTop: "10px" }}>
                  <ul>
                    {lifecycleData.durations && lifecycleData.durations.humanReadableTotal && (
                      <li>
                        <span style={{ fontWeight: "bold" }}>
                          {t("job_lifecycle.content.previous_status_accumulated_time")}:
                        </span>{" "}
                        {lifecycleData.durations.humanReadableTotal}
                      </li>
                    )}
                    {lifecycleData.lifecycle[0] &&
                      lifecycleData.lifecycle[0].value &&
                      lifecycleData?.durations?.totalCurrentStatusDuration?.humanReadable && (
                        <li>
                          <span style={{ fontWeight: "bold" }}>
                            {t("job_lifecycle.content.current_status_accumulated_time")} (
                            {lifecycleData.lifecycle[0].value}):
                          </span>
                          {lifecycleData.durations.totalCurrentStatusDuration.humanReadable}
                        </li>
                      )}
                  </ul>
                </Card>
              ) : null}
            </Card>
            <Card
              type="inner"
              title={
                <>
                  <Space direction="horizontal" size="small">
                    <Badge status="processing" count={lifecycleData.lifecycle.length} />
                    {t("job_lifecycle.content.title_transitions")}
                  </Space>
                </>
              }
            >
              <Table
                style={{
                  overflow: "auto",
                  width: "100%"
                }}
                columns={columns}
                dataSource={lifecycleData.lifecycle}
                rowKey="start"
              />
            </Card>
          </Space>
        ) : (
          <Card type="inner" style={{ textAlign: "center" }}>
            {t("job_lifecycle.content.data_unavailable")}
          </Card>
        )
      ) : (
        <Card type="inner" title={t("job_lifecycle.content.title_loading")}>
          {t("job_lifecycle.content.loading")}
        </Card>
      )}
    </Card>
  );
}

export default JobLifecycleComponent;
