import React from "react";
import ReactDOM from "react-dom/client";

import "./style.css";
import logoImg from "./logo.png";
import $ from "jquery";

// Static React component defined as function
function Header() {
  return (
    <header>
      <img src={logoImg} alt="logo" width="128" height="128" />
      <h1>
        Course Study Plan
        <br />
        <span className="subtitle">COMP3322A Modern Technologies on World Wide Web</span>
      </h1>
    </header>
  );
}

function Instruction() {
  return (
    <React.Fragment>
      <h2>Instruction</h2>
      <ul>
        <li>Add/Remove a topic to/from your study plan by clicking the respective operation.</li>
        <li>Delete a topic permanently by typing its name into the input box and clicking the "Delete" button.</li>
      </ul>
    </React.Fragment>
  );
}

function PlanTableRow(props) {
  // TableRow receives five attributes as its props:
  //   1. _id: the _id of the topic from MongoDB, which we will use to call “operateTopic”.
  //   2. name: the name of the topic.
  //   3. hour: the hours of the topic
  //   4. status: the selection status of the topic
  //   5. operateTopic: a function with two arguments, _id and op, that is to be called when the user clicks the “add” or “remove” action links, depending on the status of this topic.

  let row_class, row_operation;
  let { _id, name, hour, status, operateTopic } = props;

  if (props.status == "yes") {
    row_class = "highlight";
    row_operation = "remove";
  } else {
    row_class = "";
    row_operation = "add";
  }

  // Step 11: Complete the function PlanTableRow

  return (
    <>
      <tr class={row_class}>
        <td>{name}</td>
        <td>{hour}</td>
        <td>{status}</td>
        <td>
          <a href="#" onClick={(e) => operateTopic(_id, row_operation)}>
            {row_operation}
          </a>
        </td>
      </tr>
    </>
  );
}

function PlanTable(props) {
  return (
    <table id="plan_table">
      <tr>
        <th>Topic Name</th>
        <th>Study Hour</th>
        <th>Chosen Status</th>
        <th>Operation</th>
      </tr>
      {props.topicInfo ? (
        props.topicInfo.map((row) => (
          <PlanTableRow
            // Step 12: fill in the missing attributes to PlanTableRow

            // key is a special attribute React uses to identify list components
            key={row._id}
            // passing as parameters to child component
            _id={row._id}
            name={row.name}
            hour={row.hour}
            status={row.status}
            operateTopic={props.operateTopic}
          />
        ))
      ) : (
        <>
          <tr style={{ textAlign: "center" }}>
            <td colSpan={4}>fetching ...</td>
          </tr>
        </>
      )}
    </table>
  );
}

class DeleteForm extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      inputTopicName: "",
    };
  }

  handleInputChange(event) {
    this.setState({ inputTopicName: event.target.value });
  }

  deleteTopic() {
    // Step 13: Complete the function deleteTopic

    // calling parent function to delete topic
    this.props.deleteTopic(this.state.inputTopicName);
  }

  render() {
    return (
      <div id="delete_div">
        {JSON.stringify(this.state.test)}
        <p>Fill in a topic name to delete it from the table permanently:</p>
        <input id="input_name" placeholder="topic name" value={this.state.inputTopicName} onChange={this.handleInputChange.bind(this)} />
        <button onClick={this.deleteTopic.bind(this)}>Delete</button>
      </div>
    );
  }
}

function Footer() {
  return (
    <footer>
      <div>
        <a href="#">Back to top</a>
      </div>
    </footer>
  );
}

class App extends React.Component {
  constructor(props) {
    super(props);

    // Initialize the state of “PlanPage” with the key “topicInfo” and an empty array as the value.
    this.state = { topicInfo: "" };
  }

  componentDidMount() {
    // Step 10: Invoke updateTopics() upon page loading

    // initial fetch topic at screen load
    this.updateTopics();
  }

  updateTopics() {
    // Step 9: Implement the controller function

    // alert("we need to send an AJAX GET request for http://localhost:3001/users/get_table");
    fetch("//localhost:3001/users/get_table")
      .then((res) => res.json())
      .then((res_json) => {
        this.setState({ ...this.state, topicInfo: res_json });
        console.log(res_json);
      });
  }

  operateTopic(_id, op) {
    // Step 9: Implement the controller function

    // alert("we send a PUT request for http://localhost:3001/users/update_status with the _id and op of the operation");
    fetch("//localhost:3001/users/update_status", {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ _id, op }),
    })
      .then((res) => res.json())
      .then((res_json) => {
        console.log(res_json);

        // update table after operation
        this.updateTopics();
      });
  }

  deleteTopic(topicName) {
    // Step 9: Implement the controller function

    // alert("we need to send an AJAX DELETE request for http://localhost:3001/users/delete_topic/topicName");
    fetch(`//localhost:3001/users/delete_topic/${topicName}`, {
      method: "DELETE",
    })
      .then((res) => res.json())
      .then((res_json) => {
        console.log(res_json);

        // update table after operation
        this.updateTopics();
      });
  }

  render() {
    return (
      <>
        <Header />
        <section className="contents">
          <Instruction />
          <hr />
          <h2>Topic Plan</h2>
          <PlanTable topicInfo={this.state.topicInfo} operateTopic={this.operateTopic.bind(this)} />
          <DeleteForm deleteTopic={this.deleteTopic.bind(this)} />
        </section>
        <Footer />
      </>
    );
  }
}

export default App;
