import { useEffect, useState } from 'react';
import useSWR from 'swr';
import useUser from '../../lib/hooks/useUser';
import conditionalClass from '../../lib/utils/conditional-class';
import { Button } from '../common/Button/Button';
import { Container } from '../common/Container/Container';
import { Header } from '../common/Header/Header';
import { Paginator } from '../common/Paginator/Paginator';
import styles from './AuditPage.module.scss';

export const AuditLogDetail = ({ entry }: { entry: any }) => {
  const [revealed, setRevealed] = useState(false);
  return (
    <div className={styles.detail}>
      <span className={[styles.data, styles.ip_address].join(' ')}>
        From IP: {entry.actor_ip}
      </span>
      {entry.location && (
        <span className={[styles.data, styles.location].join(' ')}>
          Approx. location: {entry.location.city}, {entry.location.country} (
          {entry.location.ll.join(', ')})
        </span>
      )}
      {entry.actor_ua && (
        <span className={[styles.data, styles.user_agent].join(' ')}>
          User Agent: {entry.actor_ua}
        </span>
      )}
      {entry.user_agent && (
        <span className={[styles.data, styles.user_agent_info].join(' ')}>
          Browser: {entry.user_agent.browser} {entry.user_agent.version}
          {' on '}
          {entry.user_agent.platform} ({entry.user_agent.os})
        </span>
      )}
      {entry.content && (
        <span className={[styles.data, styles.content].join(' ')}>
          Log details:{' '}
          {revealed ? (
            entry.content
          ) : (
            <Button onClick={() => setRevealed(true)} variant="link">
              Reveal potentially sensitive information
            </Button>
          )}
        </span>
      )}
    </div>
  );
};

export const AuditLog = ({ entry }: { entry: any }) => {
  const [expanded, setExpanded] = useState(false);

  return (
    <div
      className={[
        styles.log,
        conditionalClass(entry.flagged, styles.flagged),
      ].join(' ')}
    >
      <div className={styles.head}>
        <span className={styles.action}>{entry.action}</span>
        <span className={styles.timestamp}>
          {new Date(entry.created_at).toString()}
        </span>
        <span className={styles.user}>{entry.actor?.username}</span>
        <Button onClick={() => setExpanded(!expanded)} variant="link">
          {expanded ? 'Hide' : 'Show'}
        </Button>
      </div>
      {expanded && <AuditLogDetail entry={entry} />}
    </div>
  );
};

export const AuditLogs = ({}) => {
  const [searchParams, setSearchParams] = useState(new URLSearchParams({}));
  const [types, setTypes] = useState<boolean[]>([]);
  const [pageIndex, setPageIndex] = useState(1);
  const { data } = useSWR(
    `/api/admin/audit?page=${pageIndex}&${searchParams.toString()}`
  );
  const filter = useSWR<string[]>('/api/admin/audit/filter');

  useEffect(() => {
    if (!filter?.data || types.length) {
      return;
    }

    setTypes(Array.from<boolean>({ length: filter.data.length }).fill(true));
  }, [types, filter.data]);

  useEffect(() => {
    if (!filter?.data || !types.length) {
      return;
    }

    const urlparams = new URLSearchParams();
    urlparams.set(
      'actions',
      filter.data
        .reduce<string[]>((array, current, index) => {
          return [...array, types[index] ? current : ''];
        }, [])
        .filter((item) => item)
        .join(',')
    );

    setSearchParams(urlparams);
  }, [filter.data, types]);

  if (!data || !filter.data) {
    return <></>;
  }

  return (
    <div className={styles.wrapper}>
      <div className={styles.filters}>
        <div className={styles.boxes}>
          {filter.data?.map((item: string, index: number) => (
            <div className={styles.box} key={item}>
              <input
                type="checkbox"
                id={'chbx' + item}
                checked={types[index]}
                onChange={(e) => {
                  const newTypes = types.slice();
                  newTypes[index] = e.target.checked;
                  setTypes(newTypes);
                }}
              />{' '}
              <label htmlFor={'chbx' + item}>{item}</label>
            </div>
          ))}
        </div>
      </div>

      <div className={styles.logs}>
        <div className={styles.log}>
          <div className={[styles.head, styles.header].join(' ')}>
            <span className={styles.action}>Action</span>
            <span className={styles.timestamp}>Time</span>
            <span className={styles.user}>Actor</span>
            <span className={styles.actions}>Actions</span>
          </div>
        </div>
        {data.list.map((entry: any) => (
          <AuditLog entry={entry} key={entry.id} />
        ))}
      </div>

      <Paginator
        setPage={setPageIndex}
        pagination={data.pagination}
      ></Paginator>
    </div>
  );
};

export const AuditPage = () => {
  const { user } = useUser({ redirectTo: '/login' });

  return (
    <>
      <Header user={user}></Header>
      <Container>
        <h1>Audit logs</h1>
        <AuditLogs />
      </Container>
    </>
  );
};
