import Layout from '../comps/Layout.js'
import ChooseFile from '../comps/ChooseFile.js'
import ChooseDirectory from '../comps/ChooseDirectory.js'
import {useState, useCallback} from 'react';
import {unzip, enumerateFiles} from '../comps/Zip.js';
import { Line } from 'rc-progress';

function Unarchive(props) {
  return (
    <div style={{margin: 5}}>
      <button disabled={!props.inputFile || !props.outputDirectory} onClick={
        async () => {
          props.setRunning(true);
          props.statusUpdater.clearStatus();
          await unzip(props.inputFile, props.outputDirectory, props.setProgress, props.statusUpdater);
          props.setRunning(false);
          props.reset();
        }
      }>3. Unarchive</button>
    </div>
  )
}

const resultState = {
  SUCCESS: 'success',
  FAIL: 'fail',
  UNKNOWN: 'unknown',
};

function StatusBox(props) {
  if (props.state == resultState.UNKNOWN)
    return null;
  return <div>{props.message}</div>;
}

function createRows(files) {
  const items = [];
  for (const file of files) 
    items.push(<li>{file}</li>);
  return items;
}

function statusUpdater(setStatus) {
  return {
    setSuccess: (msg) => {
      setStatus({status: resultState.SUCCESS, message: msg});
    },
    setError: (msg) => {
      setStatus({status: resultState.FAIL, message: msg});
    },
    clearStatus: () => {
      setStatus({status: resultState.UNKNOWN, message: null});
    },
  };
}

function Index() {
  // Declare a state variable for the input file.
  const [inputFile, setInputFile] = useState(null);

  // Declare a state variable for the output directory handle.
  const [outputDirectory, setOutputDirectory] = useState(null);

  // Declare state variables for tracking running and the progress indicator.
  const [running, setRunning] = useState(false);
  const [progress, setProgress] = useState(0);

  const [files, setFiles] = useState([]);

  const [resultStatus, setStatus] = useState({ state: resultState.UNKNOWN, message: null});

  var setInputFileInterceptor = useCallback(async (inputFile) => {
    setInputFile(inputFile);
    console.log(inputFile);
    if (inputFile != null) {
      let enumerated = await enumerateFiles(inputFile);
      setFiles(enumerated);
    }
    else {
      setFiles([]);
    }
    console.log("set files");
  }, [setInputFile, setFiles]);

  function reset() {
    setInputFile(null);
    setOutputDirectory(null);
    setFiles([]);
  }

  return (
    <Layout>
      <div>
        <ChooseFile
            inputFile={inputFile}
            setChosenFile={setInputFileInterceptor} />
        <ChooseDirectory
            chosenDirectory={outputDirectory}
            setChosenDirectory={setOutputDirectory} />
        <Unarchive
            inputFile={inputFile}
            outputDirectory={outputDirectory}
            reset={reset}
            setProgress={setProgress}
            setRunning={setRunning}
            statusUpdater={statusUpdater(setStatus)} />
        { running ?
            <Line percent={progress} strokeWidth="1" />
            : ''
        }
        { files != null && files.length != 0 && (
          <div>
            Files to extract:
            <ul>
              {createRows(files)}
            </ul>
          </div>
        )}
        <StatusBox
            resultStatus={resultStatus.state}
            message={resultStatus.message} />
      </div>
    </Layout>
  );
}

export default Index;

@@ -879,16 +879,17 @@
 state ==
+=
  resultS
@@ -900,16 +900,34 @@
 .UNKNOWN
+ %7C%7C !props.message
 )%0A    re
@@ -941,43 +941,676 @@
 ll;%0A
-  return %3Cdiv%3E%7Bprops.message%7D%3C/div%3E
+%0A  // Support message as either an array or a string.%0A  let messageList = Array.isArray(props.message) ? props.message : %5Bprops.message%5D;%0A%0A  return (%0A    %3Cdiv id=%22statusBox%22 className=%7Bprops.resultStatus%7D%3E%0A      %7B messageList.map((msg, i) =%3E %3Cdiv key=%7Bi%7D%3E%7Bmsg%7D%3C/div%3E) %7D%0A      %3Cstyle jsx%3E%7B%60%0A      #statusBox %7B%0A        padding: 5px;%0A        margin: 5px;%0A        border-radius: 0.25em;%0A        min-height: 40px;%0A      %7D%0A      #statusBox.success %7B%0A        background-color: #aaddaf;%0A      %7D%0A      #statusBox.fail %7B%0A        background-color: #ffaaaa;%0A      %7D%0A      #statusBox div %7B%0A        display: flex;%0A        flex-direction: row;%0A      %7D%0A      %60%7D%3C/style%3E%0A    %3C/div%3E%0A  )
 ;%0A%7D%0A
@@ -1827,34 +1827,33 @@
  setStatus(%7Bstat
-us
+e
 : resultState.SU
@@ -1920,34 +1920,33 @@
  setStatus(%7Bstat
-us
+e
 : resultState.FA
@@ -2018,18 +2018,17 @@
 us(%7Bstat
-us
+e
 : result
@@ -2588,17 +2588,16 @@
 eState(%7B
- 
 state: r
@@ -2910,24 +2910,84 @@
 (%5B%5D);%0A    %7D%0A
+    setStatus(%7Bstate: resultState.UNKNOWN, message: null%7D);%0A
     console.
@@ -3032,16 +3032,27 @@
 setFiles
+, setStatus
 %5D);%0A%0A  f

Add status box coloring