text: import React, { Suspense } from 'react';
  import { Layout, Divider, Modal, message, InputNumber, Button, Select, Space, Form, Input, Tabs, Tag, Switch, Card } from 'antd';
  import {
      MinusCircleOutlined,
      PlusOutlined,
      ProfileOutlined,
      FlagOutlined,
      FlagTwoTone,
      EyeOutlined,
      EyeInvisibleOutlined
  } from '@ant-design/icons';
  import { Ellipsis } from 'react-spinners-css';
  const MDEditor = React.lazy(() => import("@uiw/react-md-editor"));
  const MarkdownRender = React.lazy(() => import('./MarkdownRenderer.js'));
  
  
  const { Option } = Select;
  const { TabPane } = Tabs;
  
  const CreateChallengeForm = (props) => {
      const [form] = Form.useForm();
      const [editorValue, setEditorValue] = React.useState("")
      const [existingCats, setExistingCats] = React.useState([])
  
      useEffect(() => {
          var currentValues = form.getFieldsValue()
          currentValues.flags = [""]
  
          form.setFieldsValue(currentValues)
          let existCats = []
  
          for (let i = 0; i < props.allCat.length; i++) {
              existCats.push(<Option key={props.allCat[i]} value={props.allCat[i]}>{props.allCat[i]}</Option>)
          }
          setExistingCats(existCats)
      }, [])
  
  
  
      return (
          <Form
              form={form}
              name="create_challenge_form"
              className="create_challenge_form"
              onFinish={async (values) => {
                  props.setState({ edited: false })
                  //console.log(values)
                  if (typeof values.flags === "undefined") {
                      message.warn("Please enter at least 1 flag")
                  }
                  else {
                      //console.log(values)
                      props.setState({ loading: true })
                      if (values.visibility === "false") {
                          values.visibility = false
                      }
                      else {
                          values.visibility = true
                      }
                      const category = (typeof values.category1 !== "undefined") ? values.category1 : values.category2
                      if (typeof values.writeup !== "undefined") {
                          if (typeof values.writeupComplete === "undefined") {
                              values.writeupComplete = true
                          }
                      }
                      await fetch(window.ipAddress + "/v1/challenge/new", {
                          method: 'post',
                          headers: { 'Content-Type': 'application/json', "Authorization": window.IRSCTFToken },
                          body: JSON.stringify({
                              "name": values.name,
                              "category": category,
                              "description": values.description,
                              "points": values.points,
                              "flags": values.flags,
                              "tags": values.tags,
                              "hints": values.hints,
                              "max_attempts": values.max_attempts,
                              "visibility": values.visibility,
                              "writeup": values.writeup,
                              "writeupComplete": values.writeupComplete
                          })
                      }).then((results) => {
                          return results.json(); //return data in JSON (since its JSON data)
                      }).then((data) => {
                          //console.log(data)
                          if (data.success === true) {
                              message.success({ content: "Created challenge " + values.name + " successfully!" })
                              form.resetFields()
                          }
                          else {
                              message.error({ content: "Oops. Unknown error, please contact an admin." })
                          }
  
  
  
                      }).catch((error) => {
                          console.log(error)
                          message.error({ content: "Oops. Issue connecting with the server or client error, please check console and report the error. " });
                      })
                      props.setState({ loading: false })
  
  
                  }
  
              }}
          >
              <h1>Challenge Name:</h1>
              <Form.Item
                  name="name"
                  rules={[{ required: true, message: 'Please enter a challenge name' }]}
              >
  
                  <Input allowClear placeholder="Challenge name" />
              </Form.Item>
  
              <Divider />
  
              <h1>Challenge Category:</h1>
              <h4>Select an Existing Category: </h4>
              <Form.Item
                  name="category1"
                  rules={[{ required: !props.state.selectCatDisabled, message: 'Please enter a challenge category' }]}
              >
  
                  <Select
                      disabled={props.state.selectCatDisabled}
                      allowClear
                      showSearch
                      placeholder="Select an existing Category"
                      onChange={(value) => {
                          if (value) {
                              props.setState({ inputCatDisabled: true })
                          }
                          else {
                              props.setState({ inputCatDisabled: false })
                          }
                      }}
                  >
                      {existingCats}
                  </Select>
  
              </Form.Item>
              <h4>Enter a New Category</h4>
              <Form.Item
                  name="category2"
                  rules={[{ required: !props.state.inputCatDisabled, message: 'Please enter a challenge category' }]}
              >
  
                  <Input onChange={(e) => {
                      e.target.value.length > 0 ? props.setState({ selectCatDisabled: true }) : props.setState({ selectCatDisabled: false })
                  }} disabled={props.state.inputCatDisabled} allowClear placeholder="Enter a new challenge category" />
              </Form.Item>
  
              <Divider />
  
              <Suspense fallback={<div style={{ height: "100%", width: "100%", display: "flex", justifyContent: "center", alignItems: "center", zIndex: 15 }}>
                  <Ellipsis color="#177ddc" size={120} ></Ellipsis>
              </div>}>
                  <h1>Challenge Description (Supports <a href="https://guides.github.com/features/mastering-markdown/" target="_blank" rel="noreferrer">Markdown</a> and <a href="https://github.com/rehypejs/rehype-raw" target="_blank" rel="noreferrer">HTML</a>)):</h1>
                  <Form.Item
                      name="description"
                      rules={[{ required: true, message: 'Please enter a description' }]}
                      valuePropName={editorValue}
                  >
                      <MDEditor value={editorValue} onChange={(value) => { setEditorValue(value) }} preview="edit" />
                  </Form.Item>
                  <h3>Challenge Description Preview</h3>
                  <Card
                      type="inner"
                      bordered={true}
                      bodyStyle={{ backgroundColor: "#262626", textAlign: "center" }}
                      className="challengeModal"
                  >
                      <MarkdownRender>{editorValue}</MarkdownRender>
                  </Card>
              </Suspense>
  
  
              <Divider />
  
              <div style={{ display: "flex", flexDirection: "row", justifyItems: "space-evenly", marginLeft: "2vw" }}>
  
                  <div style={{ display: "flex", flexDirection: "column", justifyContent: "center", width: "35vw" }}>
                      <h1>Challenge Points:</h1>
                      <Form.Item
                          name="points"
                          rules={[{ required: true, message: 'Please enter challenge points' }, {
                              type: 'integer',
                              message: "Please enter a valid integer between 1-100000",
                          },]}
                          initialValue={1}
                      >
  
                          <InputNumber min={1} max={100000} style={{ width: "30ch" }} ></InputNumber>
                      </Form.Item>
  
                      <h1>Maximum Number of Attempts (Set to 0 for unlimited)</h1>
                      <Form.Item
                          name="max_attempts"
                          rules={[{ required: true, message: 'Please enter the maximum number of attempts' }, {
                              type: 'integer',
                              message: "Please enter a valid integer between 0-10000",
                          },]}
                          style={{ alignText: 'center' }}
                          initialValue={0}
                      >
  
                          <InputNumber min={0} max={10000} style={{ width: "30ch" }}></InputNumber>
                      </Form.Item>
                  </div>
  
                  <Divider type="vertical" style={{ height: "inherit" }}></Divider>
  
                  <div style={{ display: "flex", flexDirection: "column", width: "35vw", marginLeft: "2vw" }}>
                      <Form.List name="flags" >
                          {(fields, { add, remove }) => {
                              return (
                                  <div>
                                      <h1>Flags</h1>
                                      {fields.map(field => (
                                          <Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
                                              <Form.Item
                                                  {...field}
                                                  name={[field.name]}
                                                  fieldKey={[field.fieldKey]}
                                                  rules={[{ required: true, message: 'Missing flag' }]}
                                              >
                                                  <Input style={{ width: "50ch" }} placeholder="Flag" />
                                              </Form.Item>
  
                                              {fields.length > 1 ? (
                                                  <MinusCircleOutlined
                                                      className="dynamic-delete-button"
                                                      style={{ margin: '0 8px', color: "red" }}
                                                      onClick={() => {
                                                          remove(field.name);
                                                      }}
                                                  />
                                              ) : null}
                                          </Space>
                                      ))}
  
                                      <Form.Item>
                                          <Button
                                              type="dashed"
                                              onLoad={() => { if (fields.length < 1) add() }}
                                              onClick={() => {
                                                  add();
                                              }}
                                              block
                                              style={{ width: "50ch" }}
                                          >
                                              <PlusOutlined /> Add Flag
                                          </Button>
                                      </Form.Item>
  
  
                                  </div>
                              );
                          }}
                      </Form.List>
  
                      <Form.List name="tags">
                          {(fields, { add, remove }) => {
                              return (
                                  <div>
                                      <h1>Tags</h1>
                                      {fields.map(field => (
                                          <Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
  
                                              <Form.Item
                                                  {...field}
                                                  name={[field.name]}
                                                  fieldKey={[field.fieldKey]}
                                                  rules={[{ required: true, message: 'Missing tag' }]}
                                              >
                                                  <Input placeholder="Tag" style={{ width: "50ch" }} />
                                              </Form.Item>
  
  
                                              <MinusCircleOutlined
                                                  className="dynamic-delete-button"
                                                  style={{ margin: '0 8px', color: "red" }}
                                                  onClick={() => {
                                                      remove(field.name);
                                                  }}
                                              />
                                          </Space>
                                      ))}
  
                                      <Form.Item>
                                          <Button
                                              type="dashed"
                                              onClick={() => {
                                                  add();
                                              }}
                                              block
                                              style={{ width: "50ch" }}
                                          >
                                              <PlusOutlined /> Add Tag
                                          </Button>
                                      </Form.Item>
                                  </div>
                              );
                          }}
                      </Form.List>
                  </div>
              </div>
  
              <Divider />
  
              <h1>Hints</h1>
              <Form.List name="hints" >
                  {(fields, { add, remove }) => {
                      return (
                          <div>
                              {fields.map(field => (
                                  <Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
                                      <Form.Item
                                          {...field}
                                          name={[field.name, "hint"]}
                                          fieldKey={[field.fieldKey, "hint"]}
                                          rules={[{ required: true, message: 'Missing hint' }]}
                                      >
                                          <Input placeholder="Hint" style={{ width: "20vw" }} />
                                      </Form.Item>
  
                                      <Form.Item
                                          {...field}
                                          name={[field.name, "cost"]}
                                          fieldKey={[field.fieldKey, "cost"]}
                                          rules={[{ required: true, message: 'Missing cost for hint' }, {
                                              type: 'integer',
                                              message: "Please enter a valid integer between 0-10000",
                                          },]}
                                      >
                                          <InputNumber min={0} max={10000} placeholder="Cost"></InputNumber>
                                      </Form.Item>
  
                                      <MinusCircleOutlined
                                          style={{ color: "red" }}
                                          onClick={() => {
                                              remove(field.name);
                                          }}
                                      />
                                  </Space>
                              ))}
  
                              <Form.Item>
                                  <Button
                                      type="dashed"
                                      onClick={() => {
                                          add();
                                      }}
                                      block
                                      style={{ width: "50ch" }}
                                  >
                                      <PlusOutlined /> Add Hint
                                  </Button>
                              </Form.Item>
                          </div>
                      );
                  }}
              </Form.List>
  
              <h1>Writeup Link (Optional)</h1>
              <Form.Item
                  name="writeup"
                  rules={[
                      {
                          type: 'url',
                          message: "Please enter a valid link",
                      }]}
              >
  
                  <Input allowClear style={{ width: "50ch" }} placeholder="Enter a writeup link for this challenge" />
              </Form.Item>
              <div style={{ display: "flex", alignContent: "center" }}>
                  <h4 style={{ marginRight: "2ch" }}>Release Writeup Only After Completion: </h4>
                  <Form.Item
                      name="writeupComplete"
                  >
                      <Switch defaultChecked />
                  </Form.Item>
              </div>
  
              <h1>Visibility</h1>
              <Form.Item
                  name="visibility"
                  rules={[{ required: true, message: 'Please set the challenge visibility' }]}
                  initialValue="false"
              >
                  <Select style={{ width: "10vw" }}>
                      <Option value="false"><span style={{ color: "#d32029" }}>Hidden <EyeInvisibleOutlined /></span></Option>
                      <Option value="true"><span style={{ color: "#49aa19" }}>Visible <EyeOutlined /></span></Option>
                  </Select>
  
              </Form.Item>
  
              <Form.Item>
                  <div style={{ display: "flex", justifyContent: "space-between", flexDirection: "row" }}>
                      <div>
                          <Button style={{ marginBottom: "1.5vh", marginRight: "2vw", backgroundColor: "#d4b106", borderColor: "", color: "white" }} onClick={() => { props.previewChallenge(form.getFieldsValue()); }}>Preview</Button>
                          <Button loading={props.loadingStatus} type="primary" htmlType="submit" className="login-form-button" style={{ marginBottom: "1.5vh" }}>Create Challenge</Button>
                      </div>
                      <div>
                          <Button style={{ marginRight: "2vw" }} type="primary" danger onClick={() => { form.resetFields() }}>Clear</Button>
                      </div>
                  </div>
              </Form.Item>
  
          </Form>
      );
  
  };
  
  class UserChallengeCreate extends React.Component {
      constructor(props) {
          super(props);
  
          this.state = {
              mainLoading: true,
              loading: false,
              previewChallenge: {
                  name: "",
                  category: this.props.category,
                  description: "",
                  points: 0,
                  author: "",
                  created: "",
                  solves: [],
                  max_attempts: 0,
                  tags: [],
                  hints: [],
              },
              challengeTags: [],
              challengeHints: [],
              previewModal: false,
              selectCatDisabled: false,
              selectInputDisabled: false,
              edited: false
          }
      }
  
      componentDidUpdate = () => {
          if (this.state.edited) {
              window.onbeforeunload = () => { }
          }
      }
  
      componentDidMount = () => {
          fetch(window.ipAddress + "/v1/challenge/list_categories", {
              method: 'get',
              headers: { 'Content-Type': 'application/json', "Authorization": window.IRSCTFToken },
          }).then((results) => {
              return results.json(); //return data in JSON (since its JSON data)
          }).then(async (data) => {
  
              if (data.success === true) {
                  await this.setState({ allCat: data.categories })
                  await this.setState({ mainLoading: false })
              }
              else {
                  message.error({ content: "Oops. Unknown error" })
              }
  
          }).catch((error) => {
              console.log(error)
              message.error({ content: "Oops. There was an issue connecting with the server" });
          })
      }
  
      previewChallenge = (values) => {
  
          if (values.max_attempts === 0) {
              values.max_attempts = "Unlimited"
          }
          else {
              values.max_attempts = String(values.max_attempts) + "/" + String(values.max_attempts)
          }
  
          var renderTags = []
          if (typeof values.tags !== "undefined") {
              const tag = values.tags
  
              for (let x = 0; x < tag.length; x++) {
                  renderTags.push(
                      <Tag color="#1765ad">
                          {tag[x]}
                      </Tag>
                  )
              }
  
          }
  
          //Handle hints
          if (typeof values.hints !== "undefined") {
              const hints = values.hints
              var renderHints = []
  
              for (let x = 0; x < hints.length; x++) {
                  renderHints.push(
                      <Button type="primary" key={hints[x].cost} style={{ marginBottom: "1.5vh" }}>Hint {x + 1} - {hints[x].cost} Points</Button>
                  )
              }
  
          }
  
          this.setState({ previewChallenge: values, previewModal: true, challengeTags: renderTags, challengeHints: renderHints })
      }
  
      render() {
          return (
  
              <Layout style={{ margin: "20px", backgroundColor: "rgba(0, 0, 0, 0)" }}>
                  <div style={{ padding: "10px", backgroundColor: "rgba(0, 0, 0, 0.5)", border: "5px solid transparent", borderRadius: "20px" }}>
                      <Modal
                          title={null}
                          visible={this.state.previewModal}
                          footer={null}
                          bodyStyle={{ textAlign: "center" }}
                          onCancel={() => { this.setState({ previewModal: false }) }}
                      >
                          <Tabs defaultActiveKey="challenge">
                              <TabPane
                                  tab={<span><ProfileOutlined /> Challenge</span>}
                                  key="challenge"
                              >
                                  <h1 style={{ fontSize: "150%" }}>{this.state.previewChallenge.name}</h1>
                                  <div>
                                      {this.state.challengeTags}
                                  </div>
                                  <h2 style={{ color: "#1765ad", marginTop: "2vh", marginBottom: "6vh", fontSize: "200%" }}>{this.state.previewChallenge.points}</h2>
  
                                  <div className="challengeModal">
                                      <MarkdownRender>{this.state.previewChallenge.description}</MarkdownRender>
                                  </div>
  
                                  <div style={{ marginTop: "6vh", display: "flex", flexDirection: "column" }}>
                                      {this.state.challengeHints}
                                  </div>
                                  <div style={{ display: "flex", justifyContent: "center" }}>
                                      <Input style={{ width: "45ch" }} defaultValue="" placeholder={"Enter a flag"} />
                                      <Button type="primary" icon={<FlagOutlined />}>Submit</Button>
                                  </div>
                                  <div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between", marginTop: "2vh" }}>
                                      <p>Challenge Author: <em>You</em></p>
                                      <p style={{ color: "#d87a16", fontWeight: 500 }}>Attempts Remaining: {this.state.previewChallenge.max_attempts}</p>
                                  </div>
                              </TabPane>
                          </Tabs>
  
  
                      </Modal>
                      <div style={{ display: "flex", alignItems: "center", alignContent: "center" }}>
                          <h1 style={{ fontSize: "180%" }}> <FlagTwoTone /> Create New Challenge</h1>
  
                      </div>
                      {!this.state.mainLoading && this.state.allCat !== [] && (
                          <CreateChallengeForm allCat={this.state.allCat} state={this.state} setState={this.setState.bind(this)} previewChallenge={this.previewChallenge.bind(this)} loadingStatus={this.state.loading}></CreateChallengeForm>
                      )}
                      {this.state.mainLoading && (
                          <div>
                              <div className="demo-loading-container" style={{ display: "flex", flexDirection: "row", alignItems: "center", justifyContent: "center", marginTop: "10vh" }}>
                                  <Ellipsis color="#177ddc" size={120} ></Ellipsis>
                              </div>
                          </div>
                      )}
                  </div>
              </Layout>
  
          );
      }
  }
  
  export default UserChallengeCreate;