import React, { useContext, useEffect, useState } from "react";
import { get, isEmpty } from "lodash";
import styled from "styled-components";

import job from "assets/job.png";
import leftArrow from "assets/left-arrow.svg";
import KeyValueArray from "components/form-components/KeyValueArray";
import Loading from "components/Loading";
import TabRegion, { TabOption } from "components/TabRegion";
import TitleSection from "components/TitleSection";
import api from "shared/api";
import { Context } from "shared/Context";
import { ChartType } from "shared/types";
import DeploymentType from "main/home/cluster-dashboard/expanded-chart/DeploymentType";
import Logs from "../status/Logs";
import { useRouting } from "shared/routing";
import LogsSection, { InitLogData } from "main/home/cluster-dashboard/expanded-chart/logs-section/LogsSection";
import EventsTab from "main/home/cluster-dashboard/expanded-chart/events/EventsTab";
import { getPodStatus } from "main/home/cluster-dashboard/expanded-chart/deploy-status-section/util";
import { capitalize } from "shared/string_utils";
import { usePods } from "shared/hooks/usePods";
import Container from "components/porter/Container";
import Text from "components/porter/Text";
import Spacer from "components/porter/Spacer";

const readableDate = (s: string) => {
  let ts = new Date(s);
  let date = ts.toLocaleDateString();
  let time = ts.toLocaleTimeString([], {
    hour: "numeric",
    minute: "2-digit",
  });
  return `${time} on ${date}`;
};

const getLatestPod = (pods: any[]) => {
  if (!Array.isArray(pods)) {
    return undefined;
  }

  return [...pods]
    .sort((a: any, b: any) => {
      if (!a?.metadata?.creationTimestamp) {
        return 1;
      }

      if (!b?.metadata?.creationTimestamp) {
        return -1;
      }

      return (
        new Date(b?.metadata?.creationTimestamp).getTime() -
        new Date(a?.metadata?.creationTimestamp).getTime()
      );
    })
    .shift();
};

export const isRunning = (deleting: boolean, job: any, pod: any) => {
  if (deleting) {
    return false;
  }

  if (job.status?.succeeded >= 1) {
    return false;
  }

  if (job.status?.conditions) {
    if (job.status?.conditions[0]?.reason == "DeadlineExceeded") {
      return false;
    }
  }

  if (job.status?.failed >= 1) {
    return false;
  }

  if (job.status?.active >= 1) {
    // determine the status from the pod
    return pod ? pod.status.startTime : false;
  }

  return true;
};

export const renderStatus = (
  deleting: boolean,
  job: any,
  pod: any,
  time?: string
) => {
  if (deleting) {
    return <Status color="#cc3d42">Deleting</Status>;
  }

  if (job.status?.succeeded >= 1) {
    if (time) {
      return <Status color="#38a88a">Succeeded at {time}</Status>;
    }

    return <Status color="#38a88a">Succeeded</Status>;
  }

  if (job.status?.conditions) {
    if (job.status?.conditions[0]?.reason == "DeadlineExceeded") {
      return <Status color="#cc3d42">Timed Out</Status>;
    }
  }

  if (job.status?.failed >= 1) {
    return <Status color="#cc3d42">Failed</Status>;
  }

  if (job.status?.active >= 1) {
    // determine the status from the pod
    return pod ? (
      <Status color="#ffffff11">{capitalize(getPodStatus(pod?.status))}</Status>
    ) : (
      <Status color="#ffffff11">Running</Status>
    );
  }

  return <Status color="#ffffff11">Running</Status>;
};

type ExpandedJobRunTabs = "events" | "logs" | "config" | string;

const ExpandedJobRun = ({
  currentChart,
  jobRun,
  onClose,
}: {
  currentChart: ChartType;
  jobRun: any;
  onClose: () => void;
}) => {
  const { currentProject, currentCluster, setCurrentError } = useContext(
    Context
  );
  const [currentTab, setCurrentTab] = useState<ExpandedJobRunTabs>(
    currentCluster.agent_integration_enabled ? "events" : "logs"
  );
  const { pushQueryParams } = useRouting();
  const [useDeprecatedLogs, setUseDeprecatedLogs] = useState(false);

  const [pods, isLoading] = usePods({
    project_id: currentProject.id,
    cluster_id: currentCluster.id,
    namespace: jobRun.metadata?.namespace,
    selectors: [`job-name=${jobRun.metadata?.name}`],
    controller_kind: "job",
    controller_name: jobRun.metadata?.name,
    subscribed: true,
  });

  let chart = currentChart;
  let run = jobRun;

  useEffect(() => {
    return () => {
      pushQueryParams({}, ["job"]);
    };
  }, []);

  const renderConfigSection = (job: any) => {
    let commandString = job?.spec?.template?.spec?.containers[0]?.command?.join(
      " "
    );
    let envArray = job?.spec?.template?.spec?.containers[0]?.env;
    let envObject = {} as any;
    envArray &&
      envArray.forEach((env: any, i: number) => {
        const secretName = get(env, "valueFrom.secretKeyRef.name");
        envObject[env.name] = secretName
          ? `PORTERSECRET_${secretName}`
          : env.value;
      });

    // Handle no config to show
    if (!commandString && isEmpty(envObject)) {
      return <Placeholder>No config was found.</Placeholder>;
    }

    let tag = job.spec.template.spec.containers[0].image.split(":")[1];
    return (
      <ConfigSection>
        {commandString ? (
          <>
            Command: <Command>{commandString}</Command>
          </>
        ) : (
          <DarkMatter size="-18px" />
        )}
        <Row>
          Image Tag: <Command>{tag}</Command>
        </Row>
        {!isEmpty(envObject) && (
          <>
            <KeyValueArray
              envLoader={true}
              values={envObject}
              label="Environment variables:"
              disabled={true}
            />
            <DarkMatter />
          </>
        )}
      </ConfigSection>
    );
  };

  const renderEventsSection = () => {
    return (
      <EventsTab
        currentChart={currentChart}
        overridingJobName={jobRun.metadata?.name}
        setLogData={() => setCurrentTab("logs")}
      />
    );
  };

  const renderLogsSection = () => {
    if (useDeprecatedLogs || !currentCluster.agent_integration_enabled) {
      return (
        <JobLogsWrapper>
          <Logs
            selectedPod={pods[0]}
            podError={!pods[0] ? "Pod no longer exists." : ""}
            rawText={true}
          />
        </JobLogsWrapper>
      );
    }

    let initData: InitLogData = {};

    if (run.status.completionTime) {
      initData.timestamp = run.status.completionTime;
    }

    return (
      <JobLogsWrapper>
        <DeprecatedWarning>
          Not seeing your logs? Switch back to{" "}
          <DeprecatedSelect
            onClick={() => {
              setUseDeprecatedLogs(true);
            }}
          >
            {" "}
            deprecated logging.
          </DeprecatedSelect>
        </DeprecatedWarning>
        <LogsSection
          isFullscreen={false}
          setIsFullscreen={() => { }}
          overridingPodName={pods[0]?.metadata?.name || jobRun.metadata?.name}
          currentChart={currentChart}
          initData={initData}
        />
      </JobLogsWrapper>
    );
  };

  if (isLoading) {
    return <Loading />;
  }

  let options: TabOption[] = [];

  if (currentCluster.agent_integration_enabled) {
    options.push({
      label: "Events",
      value: "events",
    });
  }

  options.push(
    {
      label: "Logs",
      value: "logs",
    },
    {
      label: "Config",
      value: "config",
    }
  );

  return (
    <StyledExpandedChart>
      <BreadcrumbRow>
        <Breadcrumb onClick={onClose}>
          <ArrowIcon src={leftArrow} />
          <Wrap>Back</Wrap>
        </Breadcrumb>
      </BreadcrumbRow>
      <HeaderWrapper>
        <Container row>
          <Icon src={job} />
          <Text size={21}>
            {jobRun.metadata?.name.split('-').slice(1, -2).join('-')}
          </Text>
          <Spacer inline width="10px" />
          <Text size={21} color="#aaaabb66">
            at {run.status.completionTime ? readableDate(run.status.completionTime) : ""}
          </Text>
        </Container>
        <Spacer y={0.5} />
        <InfoWrapper>
          <LastDeployed>
            {renderStatus(
              false,
              run,
              pods[0],
              run.status.completionTime
                ? readableDate(run.status.completionTime)
                : ""
            )}
          </LastDeployed>
        </InfoWrapper>
      </HeaderWrapper>
      <Spacer y={1} />
      <BodyWrapper>
        <TabRegion
          currentTab={currentTab}
          setCurrentTab={(newTab: string) => {
            setCurrentTab(newTab);
          }}
          options={options}
        >
          {currentTab === "events" && renderEventsSection()}
          {currentTab === "logs" && renderLogsSection()}
          {currentTab === "config" && <>{renderConfigSection(run)}</>}
        </TabRegion>
      </BodyWrapper>
    </StyledExpandedChart>
  );
};

export default ExpandedJobRun;

const Icon = styled.img`
  height: 24px;
  margin-right: 15px;
`;

const ArrowIcon = styled.img`
  width: 15px;
  margin-right: 8px;
  opacity: 50%;
`;

const BreadcrumbRow = styled.div`
  width: 100%;
  display: flex;
  justify-content: flex-start;
`;

const Breadcrumb = styled.div`
  color: #aaaabb88;
  font-size: 13px;
  margin-bottom: 15px;
  display: flex;
  align-items: center;
  margin-top: -10px;
  z-index: 999;
  padding: 5px;
  padding-right: 7px;
  border-radius: 5px;
  cursor: pointer;
  :hover {
    background: #ffffff11;
  }
`;

const Wrap = styled.div`
  z-index: 999;
`;

const Row = styled.div`
  margin-top: 20px;
`;

const DarkMatter = styled.div<{ size?: string }>`
  width: 100%;
  margin-bottom: ${(props) => props.size || "-13px"};
`;

const Command = styled.span`
  font-family: monospace;
  color: #aaaabb;
  margin-left: 7px;
`;

const ConfigSection = styled.div`
  padding: 20px 30px 30px;
  font-size: 13px;
  font-weight: 500;
  width: 100%;
  border-radius: 8px;
  background: #ffffff08;
`;

const JobLogsWrapper = styled.div`
  min-height: 450px;
  height: fit-content;
  width: 100%;
  border-radius: 8px;
`;

const Status = styled.div<{ color: string }>`
  padding: 5px 10px;
  background: ${(props) => props.color};
  font-size: 13px;
  border-radius: 3px;
  height: 25px;
  color: #ffffff;
  margin-bottom: -3px;
  display: flex;
  align-items: center;
  justify-content: center;
`;

const Gray = styled.div`
  color: #ffffff44;
  margin-left: 15px;
  font-weight: 400;
  font-size: 18px;
`;

const BackButton = styled.div`
  position: absolute;
  top: 0px;
  right: 0px;
  display: flex;
  width: 36px;
  cursor: pointer;
  height: 36px;
  align-items: center;
  justify-content: center;
  border: 1px solid #ffffff55;
  border-radius: 100px;
  background: #ffffff11;

  :hover {
    background: #ffffff22;
    > img {
      opacity: 1;
    }
  }
`;

const BackButtonImg = styled.img`
  width: 16px;
  opacity: 0.75;
`;

const Placeholder = styled.div`
  min-height: 400px;
  height: 50vh;
  padding: 30px;
  padding-bottom: 70px;
  font-size: 13px;
  color: #ffffff44;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
`;

const BodyWrapper = styled.div`
  position: relative;
  overflow: hidden;
`;

const HeaderWrapper = styled.div`
  position: relative;
`;

const InfoWrapper = styled.div`
  display: flex;
  align-items: center;
  height: 20px;
`;

const LastDeployed = styled.div`
  font-size: 13px;
  margin-left: 0;
  display: flex;
  align-items: center;
  color: #aaaabb66;
`;

const TagWrapper = styled.div`
  height: 25px;
  font-size: 12px;
  display: flex;
  margin-left: 20px;
  margin-bottom: -3px;
  align-items: center;
  font-weight: 400;
  justify-content: center;
  color: #ffffff44;
  border: 1px solid #ffffff44;
  border-radius: 3px;
  padding-left: 5px;
  background: #26282e;
`;

const NamespaceTag = styled.div`
  height: 100%;
  margin-left: 6px;
  color: #aaaabb;
  background: #43454a;
  border-radius: 3px;
  font-size: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0px 6px;
  padding-left: 7px;
  border-top-left-radius: 0px;
  border-bottom-left-radius: 0px;
`;

const StyledExpandedChart = styled.div`
  width: 100%;
  z-index: 0;
  animation: fadeIn 0.3s;
  animation-timing-function: ease-out;
  animation-fill-mode: forwards;
  display: flex;
  overflow-y: auto;
  padding-bottom: 120px;
  flex-direction: column;
  overflow: visible;

  @keyframes fadeIn {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }
`;

const DeprecatedWarning = styled.div`
  font-size: 12px;
  color: #ccc;
  text-align: right;
  width: 100%;
  margin-bottom: 20px;
`;

const DeprecatedSelect = styled.span`
  cursor: pointer;
  color: #949effff;
`;
