// Copyright 2022 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { parseISO } from "date-fns";
import { useSetAtom } from "jotai";

import { FragmentType, graphql, useFragment } from "../../gql";
import BlockList from "../BlockList/BlockList";
import { endCompatSessionFamily, simplifyUrl } from "../CompatSession";
import DateTime from "../DateTime";
import ExternalLink from "../ExternalLink/ExternalLink";
import EndSessionButton from "../Session/EndSessionButton";
import LastActive from "../Session/LastActive";

import SessionDetails from "./SessionDetails";
import SessionHeader from "./SessionHeader";

export const FRAGMENT = graphql(/* GraphQL */ `
  fragment CompatSession_detail on CompatSession {
    id
    createdAt
    deviceId
    finishedAt
    lastActiveIp
    lastActiveAt
    ssoLogin {
      id
      redirectUri
    }
  }
`);

type Props = {
  session: FragmentType<typeof FRAGMENT>;
};

const CompatSessionDetail: React.FC<Props> = ({ session }) => {
  const data = useFragment(FRAGMENT, session);
  const endSession = useSetAtom(endCompatSessionFamily(data.id));

  const onSessionEnd = async (): Promise<void> => {
    await endSession();
  };

  const finishedAt = data.finishedAt
    ? [
        {
          label: "Finished",
          value: <DateTime datetime={parseISO(data.finishedAt)} />,
        },
      ]
    : [];

  const lastActiveIp = data.lastActiveIp
    ? [{ label: "IP Address", value: <code>{data.lastActiveIp}</code> }]
    : [];

  const lastActiveAt = data.lastActiveAt
    ? [
        {
          label: "Last Active",
          value: <LastActive lastActive={parseISO(data.lastActiveAt)} />,
        },
      ]
    : [];

  const sessionDetails = [
    { label: "ID", value: <code>{data.id}</code> },
    { label: "Device ID", value: <code>{data.deviceId}</code> },
    {
      label: "Signed in",
      value: <DateTime datetime={parseISO(data.createdAt)} />,
    },
    ...finishedAt,
    ...lastActiveAt,
    ...lastActiveIp,
  ];

  const clientDetails: { label: string; value: string | JSX.Element }[] = [];

  if (data.ssoLogin?.redirectUri) {
    clientDetails.push({
      label: "Name",
      value: simplifyUrl(data.ssoLogin.redirectUri),
    });
    clientDetails.push({
      label: "Uri",
      value: (
        <ExternalLink target="_blank" href={data.ssoLogin?.redirectUri}>
          {data.ssoLogin?.redirectUri}
        </ExternalLink>
      ),
    });
  }

  return (
    <BlockList>
      <SessionHeader
        backToRoute={{
          type: "sessions-overview",
        }}
      >
        {data.deviceId || data.id}
      </SessionHeader>
      <SessionDetails title="Session" details={sessionDetails} />
      {clientDetails.length > 0 ? (
        <SessionDetails title="Client" details={clientDetails} />
      ) : null}
      {!data.finishedAt && <EndSessionButton endSession={onSessionEnd} />}
    </BlockList>
  );
};

export default CompatSessionDetail;
