import React, { Component } from 'react';
import './App.css';
import API, { graphqlOperation } from '@aws-amplify/api';
import { S3Image } from 'aws-amplify-react'
import {Grid, Header, Input, List, Segment} from 'semantic-ui-react'
import { 
  VictoryBar, 
  VictoryChart, 
  VictoryAxis, 
  VictoryTheme, 
  VictoryLabel, 
  VictoryContainer} from 'victory';
import { Link } from "react-router-dom";

import debounce from 'lodash/debounce' // 1

const SearchReports = `
  query($searchQuery: String) {
    searchReports(input: $searchQuery) {
      Impression
      Findings
      PositiveSigns
      NegativeSigns
      PositiveDiagnoses
      NegativeDiagnoses
      PositiveSymptoms
      NegativeSymptoms
      Images {
        ReportId
        ImageId
        Bucket
        Key
      }
    }
  }
`

const ListReports = `
  query {
    listReports(from:0, size:100) {
      Impression
      Findings
      PositiveSigns
      NegativeSigns
      PositiveDiagnoses
      NegativeDiagnoses
      PositiveSymptoms
      NegativeSymptoms
      Images {
        ReportId
        ImageId
        Bucket
        Key
      }
    }
  }
`

const SearchPositiveICD10CMs = `
  query($searchQuery: String) {
    getPositiveICD10CMs(input: $searchQuery) {
      key
      doc_count
    }
  }
`

const SearchNegativeICD10CMs = `
  query($searchQuery: String) {
    getNegativeICD10CMs(input: $searchQuery) {
      key
      doc_count
    }
  }
`

const ListPositiveICD10CMs = `
  query {
    getAllPositiveICD10CMs {
      key
      doc_count
    }
  }
`

const ListNegativeICD10CMs = `
  query {
    getAllNegativeICD10CMs {
      key
      doc_count
    }
  }
`

function shortenLabel(name) {
  switch(name) {
    case 'Pneumothorax, unspecified':
      return 'Pneumothorax';
    case 'Pleural effusion, not elsewhere classified':
      return 'Pleural effusion';
    case 'Lobar pneumonia, unspecified organism':
      return 'Lobar pneumonia';
    case 'Pulmonary heart disease, unspecified':
      return 'Pulmonary heart disease';
    case 'Pneumonia, unspecified organism':
      return 'Pneumonia';
    case 'Other nonspecific abnormal finding of lung field':
      return 'nonspecific abnormal findings';
    case 'Abnormal findings on diagnostic imaging of other parts of musculoskeletal system':
      return 'Abnormal findings musculoskeletal system';
    case 'Disorder of bone, unspecified':
      return 'Disorder of bone';
    case 'Edema, unspecified':
      return 'Edema';
    case 'Interstitial pulmonary disease, unspecified':
      return 'Interstitial pulmonary disease';
    case 'Central corneal opacity, left eye':
      return 'Central corneal opacity';
    case 'Atherosclerotic heart disease of native coronary artery without angina pectoris':
      return 'Atherosclerotic heart disease';
    default:
      return name;
  }
}

class Search extends Component {
  state = {
    searchQuery: '',
    loading: false,
    items: []
  }
  async componentDidMount() {
    this.setState({ loading: true })
    try {
      var apiData = await API.graphql(graphqlOperation(ListReports))
      const { data: { listReports } } = apiData
      const items = listReports
      this.setState({ items, loading: false })

      apiData = await API.graphql(graphqlOperation(ListPositiveICD10CMs))
      const { data: { getAllPositiveICD10CMs } } = apiData
      const posICD10s = getAllPositiveICD10CMs.map(
            (obj, ind) => {
                return {
                    x : ind,
                    y : obj.doc_count,
                    label: shortenLabel(obj.key)
                }
            }
        );
      this.setState({ posICD10s, loading: false })

      apiData = await API.graphql(graphqlOperation(ListNegativeICD10CMs))
      const { data: { getAllNegativeICD10CMs } } = apiData
      const negICD10s = getAllNegativeICD10CMs.map(
            (obj, ind) => {
                return {
                    x : ind,
                    y : obj.doc_count,
                    label: shortenLabel(obj.key)
                }
            }
        );
      this.setState({ negICD10s, loading: false })

      // console.log(this.state)
    } catch (err) {
      console.log('error fetching data: ', err)
    }
  }
  onChange = (e) => { // 5
    const value = e.target.value
    if (value.length >0) {
      this.setState({ searchQuery: value }, () => {
        this.handleFilter(value)
      })
    }
  }
  handleFilter = debounce((val) => { // 6
    this.onSearch(val)
  }, 250)
  onSearch = async () => {
    const { searchQuery } = this.state
    // console.log('searchQuery: ', searchQuery)
    try {
      var apiData = await API.graphql(graphqlOperation(SearchReports, { searchQuery }))
      const { data: { searchReports } } = apiData
      const items = searchReports
      this.setState({ items })

      apiData = await API.graphql(graphqlOperation(SearchPositiveICD10CMs, { searchQuery }))
      const { data: { getPositiveICD10CMs } } = apiData
      const posICD10s = getPositiveICD10CMs.map(
            (obj, ind) => {
                return {
                    x : ind,
                    y : obj.doc_count,
                    label: shortenLabel(obj.key)
                }
            }
        );
      this.setState({ posICD10s })

      apiData = await API.graphql(graphqlOperation(SearchNegativeICD10CMs, { searchQuery }))
      const { data: { getNegativeICD10CMs } } = apiData
      const negICD10s = getNegativeICD10CMs.map(
            (obj, ind) => {
                return {
                    x : ind,
                    y : obj.doc_count,
                    label: shortenLabel(obj.key)
                }
            }
        );
      this.setState({ negICD10s })
    } catch (err) {
      console.log('error searching for data: ', err)
    }
  }
  render() {
    const { items, loading, negICD10s, posICD10s, searchQuery } = this.state
    return (
      <div className="App">
        { 
          !!loading && (
            <p>Searching...</p>
          )
        }
        { 
          !loading && !items.length && (
            <p>Sorry, no results.</p>
          )
        }
        <Grid container devided='vertically'>
          {
            !loading && (
              <Grid.Row columns={2} padded>
                <Grid.Column>
                  <VictoryChart theme={VictoryTheme.material}>
                    <VictoryBar  
                      horizontal
                      style={{ data: { fill: "Green" }, labels: { fontSize: 12 }}} 
                      // labelComponent={<VictoryLabel textAnchor="end" dx={0} dy={10} />}
                      data={posICD10s}/>
                    <VictoryAxis tickFormat={() => ''} />
                    <VictoryLabel x={100} y={30} text="Positive ICD10 CMs" />
                  </VictoryChart>
                </Grid.Column>
                <Grid.Column>
                  <VictoryChart theme={VictoryTheme.material}>
                    <VictoryBar 
                      horizontal 
                      style={{ data: { fill: "Red" }, labels: { fontSize: 12 } }} 
                      labelComponent={<VictoryLabel textAnchor="start" dx={0} />}
                      data={negICD10s}/>
                    <VictoryAxis tickFormat={() => ''} />
                    <VictoryLabel x={100} y={30} text="Negative ICD10 CMs" />
                  </VictoryChart>
                </Grid.Column>
              </Grid.Row>
            )
          }

          <Grid.Row columns={1} padded>
            <Grid.Column><Header size='large'>Search Terms</Header></Grid.Column>
          </Grid.Row>
          <Grid.Row columns={1} padded>
            <Grid.Column><Input
              fluid
              size='big'
              icon='search'
              onChange={this.onChange.bind(this)}
              placeholder='Search for Findings in Radiology Report'
            /></Grid.Column>
          </Grid.Row>

          { 
            !loading && items.map((item, index) => (
              <Grid.Row columns={2}>
                <Grid.Column>
                  <Header>Impression: {item.Impression}</Header>
                  <List horizontal>
                    {
                      item.Images.map(
                        (image,i) => 
                          <List.Item key={i}> 
                            <Link to={`/Image/${image.ImageId}`}>
                              <S3Image key={i} imgKey={image.Key} level='public' theme={{ photoImg: { height: '200px', width: '200px' } }}/>
                            </Link>
                          </List.Item>
                      )
                    }
                  </List>
                </Grid.Column>
                <Grid.Column>
                  <Segment.Group horizontal>
                      <Segment padded color='yellow'>
                        <Header>Signs</Header>
                          {item.PositiveSigns.map(
                            (posSigns, i) => 
                              <List.Item key={i}> 
                                <p style={{ color: 'green' }}>{posSigns}</p>
                              </List.Item>
                          )}
                          {item.NegativeSigns.map(
                            (negSigns, i) => 
                              <List.Item key={i}> 
                                <p style={{ color: 'red' }}>{negSigns}</p>
                              </List.Item>
                          )}
                      </Segment>
                      <Segment padded color='yellow'>
                        <Header>Diagnoses</Header>
                          {item.PositiveDiagnoses.map(
                            (positiveDiag, i) => 
                              <List.Item key={i}> 
                                <p style={{ color: 'green' }}>{positiveDiag}</p>
                              </List.Item>
                          )}
                          {item.NegativeDiagnoses.map(
                            (negativeDiag, i) => 
                              <List.Item key={i}> 
                                <p style={{ color: 'red' }}>{negativeDiag}</p>
                              </List.Item>
                          )}
                      </Segment>
                      <Segment padded color='yellow'>
                        <Header>Symptoms</Header>
                          {item.PositiveSymptoms.map(
                            (positiveSymp, i) => 
                              <List.Item key={i}> 
                                <p style={{ color: 'green' }}>{positiveSymp}</p>
                              </List.Item>
                          )}
                          {item.NegativeSymptoms.map(
                            (negativeSymp, i) => 
                              <List.Item key={i}> 
                                <p style={{ color: 'red' }}>{negativeSymp}</p>
                              </List.Item>
                          )}
                      </Segment>
                  </Segment.Group>
                </Grid.Column>
              </Grid.Row>
            ))
          }
        </Grid>
      </div>
    );
  }
}

export default Search