import * as React from 'react';
import Layout from '../components/Layout';
import { NextPage } from 'next';
import fetch from 'isomorphic-unfetch';
import allLanguages from '../components/allLanguages.json';
import { Machine } from 'xstate';
import { useMachine } from '@xstate/react';

export const savingMachine = Machine({
  id: 'toggle',
  initial: 'inactive',
  states: {
    inactive: {
      on: { TOGGLE: 'saving' }
    },
    saving: {
      on: { TOGGLE: 'completed' }
    },
    completed: {
      on: { TOGGLE: 'saving' }
    }
  }
});

export interface TranslationObjectType {
  [key: string]: { message: string; missing: boolean };
}

const IndexPage: NextPage<{
  translations: any;
  languages: string[];
}> = props => (
  <Layout title="Flight Translating" languages={props.languages}>
    <div
      style={{
        display: 'grid',
        gridAutoFlow: 'column',
        paddingTop: '68px'
      }}
    >
      {props.languages
        .filter(fileName => fileName !== 'default.json')
        .map((key: string) => {
          return (
            <Translation
              translation={props.translations[key]}
              defaultText={props.translations['default.json']}
              language={key.split('.')[0]}
              key={key}
            />
          );
        })}
    </div>
  </Layout>
);

export function Translation({
  translation,
  defaultText,
  language
}: {
  translation: TranslationObjectType;
  defaultText: TranslationObjectType;
  language: string;
}) {
  const [onlyShowEmpty, setOnlyShowEmpty] = React.useState(false);
  const [current, send] = useMachine(savingMachine);
  const [translationValues, setTranslationValues] = React.useState(translation);

  function handleEmptySwitch(e: React.ChangeEvent<HTMLInputElement>) {
    setOnlyShowEmpty(e.target.checked);
  }

  const formRef = React.createRef<HTMLFormElement>();

  const translationPercentage = Math.floor(
    (Object.values(translation).filter(({ missing }) => !missing).length /
      Object.values(translation).length) *
      100
  );
  const isFullTranslation = translationPercentage === 100;

  async function handleSubmit(lang: string) {
    send('TOGGLE');
    const formData = formRef.current ? new FormData(formRef.current) : null;

    let payload: any = {};

    if (formData) {
      formData.forEach((value, key) => {
        payload[key] = value;
      });
    }

    const result = await fetch(`http://localhost:8080/translations/${lang}`, {
      method: 'PATCH',
      body: JSON.stringify(payload),
      headers: {
        'Content-Type': 'application/json'
      }
    });

    const resp = await result.json();
    send('TOGGLE');
    setTranslationValues(resp);
  }

  const entries = Object.entries(translationValues);
  entries.sort((a, b) => (a[0] > b[0] ? 1 : -1));

  // const missingValues = Object.entries(translation).filter(
  //   (t: any) => t[1].missing
  // );

  const languageObject = (allLanguages as {
    [key: string]: { name: string; nativeName: string };
  })[language];

  const languageName = !!languageObject
    ? `${languageObject.name.split(',')[0].split(';')[0]} (${language})`
    : language;

  return (
    <div className="container">
      <form
        ref={formRef}
        name={language}
        id={language}
        onSubmit={e => {
          e.preventDefault();
          handleSubmit(language);
        }}
      >
        <div className="heading-section">
          <h1>{languageName}</h1>
          <div>
            <input
              type="checkbox"
              onChange={handleEmptySwitch}
              id={`onlyEmpty_${language}`}
              disabled={isFullTranslation}
            />{' '}
            <label
              className={`show-empty ${isFullTranslation ? 'disabled' : ''}`}
              htmlFor={`onlyEmpty_${language}`}
            >
              Only show empty?
            </label>
          </div>
          <div className="percentage-bar-container">
            <div
              className="percentage-bar"
              style={{
                width: `${translationPercentage}%`,
                backgroundColor: isFullTranslation ? '#51bb51' : '#2f80ed'
              }}
            ></div>
          </div>
          <div className="translation-percentage-text">
            {translationPercentage}% translated
          </div>
        </div>
        <ul>
          {entries.map(([key, val]: any) => {
            return (
              <li
                style={{
                  display: onlyShowEmpty && !val.missing ? 'none' : 'block'
                }}
                key={`${key}`}
              >
                <label className="input-title">
                  {defaultText[key].message}
                </label>
                <span className="message-code">{key}</span>
                <input
                  defaultValue={val.message}
                  type="text"
                  name={key}
                  style={{
                    borderColor: val.missing ? 'red' : '#a59898'
                  }}
                />
              </li>
            );
          })}
        </ul>
        <button type="submit" onClick={() => handleSubmit(language)}>
          Submit
        </button>
        {current.matches('saving') && <span className="status">Saving...</span>}
        {current.matches('completed') && (
          <span className="status saved">Saved!</span>
        )}
      </form>
      <style jsx>{`
        .container {
          font-family: sans-serif;
          min-width: 350px;
        }
        .heading-section {
          margin: 0 1.5rem;
        }
        h1 {
          font-size: 1.5rem;
        }
        ul {
          padding: 0;
        }
        ul li {
          padding: 1rem 1.5rem;
        }
        ul li:nth-child(odd) {
          background: ${onlyShowEmpty ? 'transparent' : '#efefef'};
        }
        label.input-title,
        span.message-code {
          display: block;
        }
        label {
          font-weight: bold;
          font-size: 0.75rem;
          margin-bottom: 2px;
        }
        .show-empty.disabled {
          cursor: not-allowed;
          opacity: 0.5;
        }
        span.message-code {
          font-size: 0.625rem;
          color: gray;
          margin-bottom: 8px;
        }
        input:disabled {
          cursor: not-allowed;
        }
        input[type='text'] {
          font-family: sans-serif;
          border: 1px solid #a59898;
          border-radius: 6px;
          width: 100%;
          max-width: 350px;
          box-sizing: border-box;
          padding: 0.75em;
        }
        input[type='text']:focus {
          outline: none;
        }
        button[type='submit'] {
          background-color: #2f80ed;
          color: #fff;
          border-radius: 4px;
          padding: 0.5rem 1rem;
          height: 34px;
          font-size: 0.925rem;
          margin-left: 1.5rem;
          margin-bottom: 1rem;
          cursor: pointer;
        }
        button:focus {
          outline: none;
          background-color: #2067c5;
        }
        span.status {
          margin-left: 0.5rem;
          font-size: 0.825rem;
          font-weight: bold;
        }
        span.status.saved {
          color: #2f80ed;
        }
        .percentage-bar-container {
          height: 8px;
          width: 100%;
          max-width: 350px;
          border-radius: 8px;
          border: 1px solid gray;
          margin-top: 0.5rem;
        }
        .percentage-bar {
          background: #2f80ed;
          height: 100%;
        }
        .translation-percentage-text {
          margin-top: 0.25rem;
          font-size: 0.75rem;
        }
      `}</style>
    </div>
  );
}

IndexPage.getInitialProps = async function() {
  const res = await fetch('http://localhost:8080/translations');
  const data = await res.json();

  const languages = Object.keys(data);

  return {
    translations: data,
    languages
  };
};

export default IndexPage;
