import Head from 'next/head'
import React, { Fragment, ReactElement, useEffect, useState } from 'react'
import { State, Status } from '../@types'
import styles from '../styles/Home.module.css'
import { getData } from '../utils/getData'
import LogoAsset from '../images/logo.svg'
import CheckAsset from '../images/check.svg'
import addresses from '@oceanprotocol/contracts/addresses/address.json'

function statusIcon(state: State): ReactElement {
  if (state === State.Up) {
    return <CheckAsset className={`${styles.icon} ${styles.check}`} />
  } else if (state === State.Down) {
    return <span className={styles.icon}>🚨</span>
  } else {
    return <span className={styles.icon}>🚧</span>
  }
}

function statusStyle(state: State) {
  if (state === State.Down) {
    return styles.down
  } else if (state === State.Warning) {
    return styles.warning
  } else {
    return styles.up
  }
}

export default function HomePage(): ReactElement {
  const [data, setData] = useState<{ [key: string]: Status }>()

  useEffect(() => {
    async function getStatuses() {
      const data = await getData()
      setData(data)
    }
    getStatuses()
  }, [])

  return (
    <div className={styles.container}>
      <Head>
        <title>Ocean Protocol Status</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <header>
        <LogoAsset className={styles.logo} />

        <h1 className={styles.title}>Ocean Protocol Status</h1>
        <p className={styles.description}>
          Status overview of all{' '}
          <a href="https://docs.oceanprotocol.com/core-concepts/networks">
            deployed components
          </a>{' '}
          hosted by the Ocean Protocol Foundation.
        </p>
      </header>

      <main>
        {Object.entries(data || {}).map(([key, value]) => {
          const networkKey = key

          return (
            <Fragment key={networkKey}>
              <h2 className={styles.networkName}>{networkKey}</h2>
              <div className={styles.grid}>
                {Object.entries(value)
                  .filter(
                    // TODO: Remove this filter if we fix this on API level
                    // Needs a new `components` key under Status response
                    ([key]) =>
                      key !== 'currentBlock' &&
                      key !== 'lastUpdatedOn' &&
                      key !== 'network' &&
                      key !== '_id' &&
                      key !== '__v'
                  )
                  .map(([key, value]) => (
                    <div
                      key={key}
                      className={`${styles.card} ${statusStyle(
                        // TODO: all component states should be of type Status on API level
                        key === 'market' || key === 'dataFarming'
                          ? value
                          : value.status
                      )}`}
                    >
                      <h2 className={styles.titleComponent}>
                        {statusIcon(
                          key === 'market' || key === 'dataFarming'
                            ? value
                            : value.status
                        )}{' '}
                        {key}
                        <code
                          className={styles.version}
                          title="deployed version"
                        >
                          {value.version}
                        </code>
                      </h2>

                      {value.statusMessages && value.statusMessages !== '' && (
                        <ul className={styles.messages}>
                          {value.statusMessages
                            .split(',')
                            .map((message: string, i: number) => (
                              <li key={i} className={styles.statusMessage}>
                                {message}
                              </li>
                            ))}
                        </ul>
                      )}
                    </div>
                  ))}
              </div>

              <details className={styles.contracts}>
                <summary>
                  <h3 className={styles.titleComponent}>Deployed Contracts</h3>
                </summary>
                <ul>
                  {Object.entries((addresses as any)[networkKey]).map(
                    ([key, value]) =>
                      key !== 'chainId' &&
                      key !== 'startBlock' && (
                        <li key={key}>
                          <code className={styles.key}>{key}</code>:{' '}
                          <code>{JSON.stringify(value)}</code>
                        </li>
                      )
                  )}
                </ul>
              </details>
            </Fragment>
          )
        })}
      </main>

      <footer className={styles.footer}></footer>
    </div>
  )
}
