import React, { Component } from "react";
import { useNavigate } from "react-router-dom";
import { useAppDispatch } from "../../app/hooks";
import DataUtils, { SearchResults } from "../data/DataUtils";
import { setTitle } from "../page-title/pageTitleSlice";
import { setResults } from "../search-results/searchResultsSlice";
import styles from "./SearchForm.module.css";

interface FCProps {}

interface Props extends FCProps {
  navigate: any;
  dispatch: any;
}

interface State {
  pdStart: string;
  pdEnd: string;
  widthMin: string;
  widthMax: string;
  depthMin: string;
  depthMax: string;
  cellType: string;
  area: string;
  geneType: string;
  keyword: string;
}

class SearchForm extends Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = {
      pdStart: "44",
      pdEnd: "100",
      widthMin: "317",
      widthMax: "512",
      depthMin: "90",
      depthMax: "230",
      cellType: "any",
      area: "all",
      geneType: "all",
      keyword: "",
    };
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleSelectChange = this.handleSelectChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  componentDidMount() {
    this.props.dispatch(setTitle("Database Search"));
  }

  doSearch(): SearchResults {
    const toNumber = (v: string): number => parseInt(v.trim(), 10);
    const params = {
      pdStart: toNumber(this.state.pdStart),
      pdEnd: toNumber(this.state.pdEnd),
      widthMin: toNumber(this.state.widthMin),
      widthMax: toNumber(this.state.widthMax),
      depthMin: toNumber(this.state.depthMin),
      depthMax: toNumber(this.state.depthMax),
      cellType: this.state.cellType.trim(),
      area: this.state.area.trim(),
      geneType: this.state.geneType.trim(),
      keyword: this.state.keyword.trim(),
    };
    return DataUtils.search(params);
  }

  handleInputChange: React.ChangeEventHandler<HTMLInputElement> = (event: React.ChangeEvent<HTMLInputElement>) => {
    const target = event.target;
    const value = target.value;
    const name = target.name;
    switch (name) {
      case "pdStart":
        this.setState({ pdStart: value });
        break;
      case "pdEnd":
        this.setState({ pdStart: value });
        break;
      case "widthMin":
        this.setState({ widthMin: value });
        break;
      case "widthMax":
        this.setState({ widthMax: value });
        break;
      case "depthMin":
        this.setState({ depthMin: value });
        break;
      case "depthMax":
        this.setState({ depthMax: value });
        break;
      case "cellType":
        this.setState({ cellType: value });
        break;
      case "keyword":
        this.setState({ keyword: value });
        break;
    }
  };

  handleSelectChange: React.ChangeEventHandler<HTMLSelectElement> = (event: React.ChangeEvent<HTMLSelectElement>) => {
    const target = event.target;
    const value = target.value;
    const name = target.name;
    switch (name) {
      case "area":
        this.setState({ area: value });
        break;
      case "geneType":
        this.setState({ geneType: value });
        break;
    }
  };

  handleSubmit: React.FormEventHandler<HTMLFormElement> = (event: React.FormEvent) => {
    event.preventDefault();
    const results = this.doSearch();
    this.props.dispatch(setResults(results));
    this.props.navigate("/search/results");
  };

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <div className={styles.formGroup}>
          <label htmlFor="pdStart">Postnatal Days</label>
          <div className={styles.value}>
            <input type="number" name="pdStart" className={styles.txtParam} value={this.state.pdStart} onChange={this.handleInputChange} />
            <span className={styles.range}>-</span>
            <input type="number" name="pdEnd" className={styles.txtParam} value={this.state.pdEnd} onChange={this.handleInputChange} />
          </div>
        </div>
        <div className={styles.formGroup}>
          <label htmlFor="widthMin">Recording volume width (height)</label>
          <div className={styles.value}>
            <input type="number" name="widthMin" className={styles.txtParam} value={this.state.widthMin} onChange={this.handleInputChange} />
            <span className={styles.range}>-</span>
            <input type="number" name="widthMax" className={styles.txtParam} value={this.state.widthMax} onChange={this.handleInputChange} />
          </div>
        </div>
        <div className={styles.formGroup}>
          <label htmlFor="depthMin">Recording volume depth</label>
          <div className={styles.value}>
            <input type="number" name="depthMin" className={styles.txtParam} value={this.state.depthMin} onChange={this.handleInputChange} />
            <span className={styles.range}>-</span>
            <input type="number" name="depthMax" className={styles.txtParam} value={this.state.depthMax} onChange={this.handleInputChange} />
          </div>
        </div>
        <div className={styles.formGroup}>
          <label htmlFor="cellType">Cell type (E, I, G, P, S, or "any")</label>
          <div className={styles.value}>
            <input type="text" name="cellType" className={styles.txtParamStr} value={this.state.cellType} onChange={this.handleInputChange} />
          </div>
        </div>
        <div className={styles.formGroup}>
          <label htmlFor="area">Target area</label>
          <div className={styles.value}>
            <select name="area" className={styles.selParam} value={this.state.area} onChange={this.handleSelectChange}>
              <option value="all">All</option>
              <option value="L2/3, V1">L2/3 in the visual cortex</option>
            </select>
          </div>
        </div>
        <div className={styles.formGroup}>
          <label htmlFor="geneType">Mouse line</label>
          <div className={styles.value}>
            <select name="geneType" className={styles.selParam} value={this.state.geneType} onChange={this.handleSelectChange}>
              <option value="all">All</option>
              <option value="VGAT-Venus">VGAT-Venus</option>
              <option value="PV/myrGFP-LDLRct">PV/myrGFP-LDLRct</option>
              <option value="Dlx5/6-GCaMP3">Dlx5/6-GCaMP3</option>
            </select>
          </div>
        </div>
        <div className={styles.formGroup}>
          <label htmlFor="keyword">Keyword Search</label>
          <div className={styles.value}>
            <input type="text" name="keyword" className={styles.txtKeyword} value={this.state.keyword} onChange={this.handleInputChange} />
          </div>
        </div>
        <div className={styles.formGroup}>
          <div className={styles.submit}>
            <input type="submit" value="Search" />
          </div>
        </div>
      </form>
    );
  }
}

const SearchFormFC: React.FC<FCProps> = (props: FCProps) => {
  const navigate = useNavigate();
  const dispatch = useAppDispatch();
  return <SearchForm navigate={navigate} dispatch={dispatch} />;
};

export default SearchFormFC;
