import React, { Component, Fragment } from 'react';
import CircularProgress from '@material-ui/core/CircularProgress';

const _ = require('lodash')

//import { makeStyles } from '@material-ui/core/styles';
import FormControl from '@material-ui/core/FormControl';
import Select from '@material-ui/core/Select';
import InputLabel from '@material-ui/core/InputLabel';
import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles';
import setVal from '../utils/set-val';
import getFilterQSs from '../utils/get-filter-qss';

import EnhancedTable from './enhanced-table.jsx';
import TeamStatTable from './team-stat-table.jsx';
import TeamScheduleTable from './team-schedule-table.jsx';
import TeamRosterTable from './team-roster-table.jsx';
import TeamDepthTable from './team-depth-table.jsx';
import TeamInjuryTable from './team-injury-table.jsx';
import TeamTransactionTable from './team-transaction-table.jsx';

const teamData = require('../config/team-data.json');

import { Transition } from 'react-transition-group';

const duration = 300;

const defaultStyle = {
  transition: 'opacity 200ms ease-in-out',
  opacity: 0,
}

const transitionStyles = {
  entering: { opacity: 1, visibility: 'visible' },
  entered:  { opacity: 1, visibility: 'visible' },
  exiting:  { opacity: 0, visibility: 'visible' },
  exited:  { opacity: 0, visibility: 'hidden' },
};

const theme = createMuiTheme({
  overrides: {
    MuiSelect: {
      select: {
        "&:focus": {
          backgroundColor: '#ffffff'
        }
      }
    }
  }
});

const seasonTypes = {
  baseball: [{value: '1', displayValue: 'Spring Training'}, {value: '2', displayValue: 'Regular Season'}, {value: '3', displayValue: 'Postseason'}],
  basketball: [{value: '1', displayValue: 'Preseason'}, {value: '2', displayValue: 'Regular Season'}, {value: '3', displayValue: 'Postseason'}],
  football: [{value: '1', displayValue: 'Preseason'}, {value: '2', displayValue: 'Regular Season'}, {value: '3', displayValue: 'Postseason'}]
};

const selectStyle = {background: 'white'},
      formControlStyle ={marginTop: 6, marginBottom: 12};

export class TeamTablePanel extends Component {
  constructor(props) {
    super();
    this.state = {
      stats: null,
      selects: {
        stats: [
        ],
      },
      leagues: {
        mlb: {},
        mls: {},
        nba: {},
        nfl: {}
      },
      selectType: 'statistics',
      selectCat: '',
      selectSubCat: '',
      select1: '',
      data: null,
      selectTypes: {
        statistics: {
          name: 'statistics',
          title: 'Stats',
          params: ['athletes', 'statistics'],
          filters: [
            {name: 'season', title: 'Season', options: []},
            {name: 'seasontype', title: 'Season Type', options: []}
          ]
        },
        schedule: {
          name: 'schedule',
          title: 'Schedule',
          params: ['schedule'],
          filters: [
            {name: 'season', title: 'Season', options: []},
            {name: 'seasontype', title: 'Season Type', options: []}
          ]
        },
        roster: {name: 'roster', title: 'Roster', params: ['roster'], filters: []},
        'depth-chart': {name: 'depth-chart', title: 'Depth Chart', filters: []},
        injuries: {name: 'injuries', title: 'Injuries', filters: []},
        transactions: {name: 'transactions', title: 'Transactions', filters: [
          {name: 'season', title: 'Season', options: []},
          {name: 'month', title: 'Month', options: []}
        ]},
        contracts: {name: 'contracts', title: 'Contracts', params: ['roster'], filters: []}
      }
    };
    
    this.changeSelectType = this.changeSelectType.bind(this);
    this.changeSelectCat = this.changeSelectCat.bind(this);
    this.changeSelectSubCat = this.changeSelectSubCat.bind(this);
    this.changeSelect1 = this.changeSelect1.bind(this);
    this.changeFilter = this.changeFilter.bind(this);
    this.filterMap = this.filterMap.bind(this);
    this.getFetchURL = this.getFetchURL.bind(this);
    this.getFilterOpts = this.getFilterOpts.bind(this);
    this.fetchSchedule = this.fetchSchedule.bind(this);
    this.prefetchSeasonTypes = this.prefetchSeasonTypes.bind(this);
    this.setSubCats = this.setSubCats.bind(this);
    this.onload = this.onload.bind(this);
    this.setFilters = this.setFilters.bind(this);
  }
  
  componentDidMount() {
    console.log('mounted team table')
    const props = this.props;
    this.state.team = props.team;
    this.state.winWidth = props.winWidth;
    this.fetchData().then(this.fetchSchedule);
    theme.overrides.MuiSelect.select['&:focus'].borderColor = '#' + props.team.color;
  }
  
  componentDidUpdate(prevProps) {
    const props = this.props;
    console.log('team table trying to update', props, prevProps);
    
    if (props.team.slug !== prevProps.team.slug || props.winWidth !== prevProps.winWidth) {
      console.log('component updated team table')
      this.setState({
        team: props.team,
        winWidth: props.winWidth,
        loading: true
      });
      this.fetchData().then(this.fetchSchedule);
      theme.overrides.MuiSelect.select['&:focus'].borderColor = '#' + props.team.color;
    }
  }
  
  fetchSchedule() {
    const {props, state} = this;
    fetch(this.getFetchURL(['schedule']),
    {headers: {"athleteID": state.aid}});
  }
  
  fetchData(url) {
    const state = this.state;
    const selectType = state.selectType;
    const selectTypes = state.selectTypes;
    const selectedType = selectTypes[selectType];
    
    console.log('fetch', selectType, state.selectTypes)
    
    let initRun = false;
    
    if (!url) {
      console.log('fresh url', selectedType)
      url = this.getFetchURL(selectedType.params);
      initRun = true;
    }
    
    return fetch(url)
    .then(resp => resp.json())
    .then(json => {
      
      let newState = {loading: false};
      
      if (selectType === 'statistics' || selectType === 'schedule') {
        console.log('seasoncheck', json.requestedSeason, json.season);
        const season = json.requestedSeason || json.season;
        json.filterValues = {season: season.year};
        json.filterValues.seasontype = season.type;
        
        const sport = this.props.team.sport,
              seasonTypeFilter = selectedType.filters.find(filter => filter.name === 'seasontype');
        
        if (initRun) {
          console.log('changing season types');

          seasonTypeFilter.options = seasonTypes[sport];
          const defaultYear = 2004,
                firstYear = Math.max(defaultYear, this.props.team.year),
                opts = [];
          console.log('selectedType', season.year, firstYear, this.props.team, selectedType);
          for (let year=season.year; year>=firstYear; --year) {
            //console.log('loop year', year);
            opts.push({value: year, displayValue: year});
          }
          selectedType.filters[0].options = opts;
          newState.selectTypes = selectTypes;
          console.log('got seasons', opts, selectedType, selectedType.filters[0].options[0], selectedType.filters[1].options[0]);
          
          if (selectType === 'statistics') {
            this.props.gotStandings(json.team.recordSummary, json.team.standingSummary);
            console.log('check set season', state.leagues[this.props.team.league].season, season.year);
            if (!state.leagues[this.props.team.league].season) {
              state.leagues[this.props.team.league].season = season.year;
            }
          }
          newState.selectSubCat = 0;
        }
        
        this.prefetchSeasonTypes(season.year, seasonTypeFilter);
        
        
        if (selectType === 'statistics') {
          if (sport === 'football' || sport === 'baseball') {
            json.subCats = json.results.map(item => ({name: item.name, title: item.displayName}));
          }
          else {
            json.subCats = [{name: 'general', title: 'General'}, {name: 'scoring', title: 'Scoring'}];
          }
          //newState.selectSubCat = 0; //json.results[0].name;
        }
      }
      else if (selectType === 'roster') {
        if (!json.athletes[0].position.hasOwnProperty('id')) {
          json.subCats = json.athletes.map(item => ({name: _.camelCase(item.position), title: _.startCase(item.position)}));
          //newState.selectSubCat = 0;
        }
      }
      
      newState[selectType] = json;
      this.setState(newState);
    })
    .catch((err) => {
      console.error('caught queue', err);
    })
  }
  
  setSubCats(cat, data) {
    this.state[cat].subCats = data;
    this.setState({[cat]: this.state[cat]});
  }
  
  getFetchURL(params) {
    const {sport, league, abbreviation} = this.props.team;
    return 'https://site.web.api.espn.com/apis/site/v2/sports/' + sport + '/' + (sport === 'soccer' ? '' : league + '/') + 'teams/' + abbreviation + '/' + params.join('/');
  }
  
  changeSelectType(ev) {
    this.updateChart({selectType: ev.target.value, selectCat: 0, selectSubCat: 0});
  }
  
  changeSelectCat(ev) {
    const value = ev.target.value;
    console.log('changeCat', value, ev.target);
    
    if (value !== 'depth-chart' && value !== 'injuries' && value !== 'transactions')
      this.setState({loading: true, selectType: value, selectCat: 0, selectSubCat: 0}, this.fetchData);
    else {
      if (value === 'transactions') {
        const opts = [],
              state = this.state;
        for (let year=state.leagues[this.props.team.league].season; year>=2008; --year) {
          opts.push({value: year, displayValue: year});
        }
        console.log('transaction season opts', opts);
        state.selectTypes[value].filters[0].options = opts;
      }
      
      this.setState({loading: true, selectType: value, selectCat: 0, selectSubCat: 0});
    }
  }
  
  changeSelectSubCat(ev) {
    //this.updateChart({selectSubCat: ev.target.selectedIndex});
    const selectType = this.state.selectType;
    console.log('change subcat', selectType);
    //if (selectType === 'stats' || selectType === 'roster')
    this.setState({selectSubCat: ev.target.selectedIndex})
  }
  
  onload() {
    this.setState({loading: false});
  }
  
  setFilters(filterOpts, filterValues) {
    const state = this.state;
    
    console.log('setfilters', state.selectType, filterOpts, filterValues)
    
    for (let filterOptName in filterOpts) {
      state.selectTypes[state.selectType].filters.find(filter => filter.name === filterOptName).options = filterOpts[filterOptName];
    }
    
    this.setState({[state.selectType]: {filterValues: filterValues}, selectTypes: state.selectTypes});
  }
  
  changeSelect1(ev) {
    this.updateChart({select1: ev.target.value});
  }
  
  prefetchSeasonTypes(year, seasonTypeFilter) {
    console.log('prefetch season types', this.props.team.sport, year, seasonTypeFilter.options)
    const state = this.state,
          options = [];
    
    const url = this.getFetchURL(state.selectTypes[state.selectType].params) + '?season=' + year + '&seasontype=';
    let respCt = 0;
    
    for (let seasonType of seasonTypes[this.props.team.sport]) {
      fetch(url + seasonType.value)
      .then(resp => resp.json())
      .then(json => {
        const season = (json.status === 'success') ? (json.requestedSeason || json.season) : null;
        console.log('got seasontype', season.year, year, season.type, seasonType.value)
        if (season.year == year && season.type == seasonType.value) {
          options[season.type] = {value: season.type, displayValue: season.name};
        }
        
        ++respCt;
        console.log('updated seasontype', respCt, options, seasonTypeFilter, state.selectTypes[state.selectType]);
        if (respCt === 3) {
          
          seasonTypeFilter.options = options;
          console.log('resetstate', seasonTypeFilter, state.selectTypes[state.selectType].filters[1]);
          this.setState({selectTypes: state.selectTypes})
        }
      })
      .catch((err) => {
        ++respCt;
        console.error('got seasontype failed', year, seasonType.value);
        if (respCt === 3) {
          console.log('resetstate');
          seasonTypeFilter.options = options;
          this.setState({selectTypes: state.selectTypes})
        }
      });
    }
  }
  
  changeFilter(ev) {
    const state = this.state,
          selectType = state.selectType,
          selectedType = state.selectTypes[selectType],
          filterName = ev.target.id.replace('select-filter-', ''),
          filterVal = ev.target.value;
          
    this.setState({loading: true});
    
    console.log('changeFilter', filterName, filterVal, selectType, state[selectType]);
    
    if (selectType === 'statistics' && filterName === 'season') {
      this.fetchData(this.getFetchURL(selectedType.params) + '?season=' + filterVal);
    }
    else if (selectType === 'transactions') {
      state[selectType].filterValues[filterName] = filterVal;
      console.log('transaction filter change', state[selectType]);
      this.setState({selectTypes: state.selectTypes})
    }
    else {
      let filters = {};
      state.selectTypes[selectType].filters.map((filter) => {
        filters[filter.name] = state[selectType].filterValues[filter.name];
      });
      filters[filterName] = filterVal;
      
      const qs = new URLSearchParams(filters).toString();
      this.fetchData(this.getFetchURL(selectedType.params) + '?' + qs);
    }
  }
  
  updateChart(newStateData) {
    const {props, state} = this;
  }
  
  getFilterOpts(opt, i) {
    return (
      <option key={i} value={opt.value}>{opt.displayValue}</option>
    );
  }
  
  filterMap(filter, fi) {
    if (filter.options.length) {
      const selectedType = this.state[this.state.selectType];
      console.log('filtermap', filter.name, selectedType ? selectedType.filterValues[filter.name] : null);
      return this.buildSelect(fi,
        'select-filter-' + filter.name,
        filter.title,
        this.changeFilter,
        filter.options.map(this.getFilterOpts),
        selectedType ? selectedType.filterValues[filter.name].toString() : null
      );
    }
    return null;
  }
  
  buildSelect(key, id, label, onChange, opts, value) {
    const props = (typeof value !== 'undefined') ? {defaultValue: value, value: value} : {};
    console.log('buildselect', label, props, opts)
    //const props = (filterKey) ? {renderValue: () => this.state[this.state.selectType].filterValues[filterKey]} : {};
    return (
      <FormControl key={key} variant="outlined" style={formControlStyle}>
        <InputLabel htmlFor={id}>{label}</InputLabel>
        <Select
          native
          onChange={onChange}
          style={selectStyle}
          label={label}
          {...props}
          inputProps={{
            name: label,
            id: id,
          }}
        >{opts}</Select>
      </FormControl>
    );
  }
  
  render() {
    const props = this.props,
          stats = props.stats,
          state = this.state,
          selectType = state.selectType,
          winWidth = this.props.winWidth,
          selects = state.selects[selectType],
          selectTypes = this.state.selectTypes;
    
    const selectedTypeData = state[selectType];
    const selectedType = selectTypes[selectType];
    //const selectedCats = selectedType ? _.get(state[selectType].categories, selectedType.filters.reduce((acc, {name, value}) => (acc + ((acc) ? '.' : '') + name + '.' + value), '')) : null;
    
    console.log('RENDER', selectType, selectedTypeData, state, props);
    
    let selectCatOpts, selectSubCatOpts, select1Opts, selectSubCatLabel, filterSelects, splitOpts, filterOpts, leagueOpts;
    
    const hasData = (!!selectedTypeData || selectType === 'depth-chart' || selectType === 'injuries' || selectType === 'transactions')
    
    if (hasData) {
      console.log('selectedType', selectType, selectedTypeData);
      //const cats = (selectType === 'stats') ? selectedType.categories : selectedType.splitCategories;
      
      selectCatOpts = Object.keys(selectTypes).map((key, i) =>
        <option key={i} value={selectTypes[key].name}>{selectTypes[key].title}</option>
      );
      
      //const selectCat = cats[state.selectCat];
      filterSelects = selectedType.filters.map(this.filterMap);
        
      /*const selectTypeOpts = selectTypes.map((item, i) =>
        <option key={i} value={item.name}>{item.title}</option>
      );*/
      const selectTypeOpts = null;
        
      if (selectType === 'statistics') {
        selectSubCatLabel = 'Stat';
        
        selectSubCatOpts = selectedTypeData.subCats.map((item, i) =>
          <option key={i} value={item.name}>{item.title}</option>
        );
        
        select1Opts = null;
      }
      else if (selectType === 'schedule') {
        selectSubCatLabel = 'Test';
        select1Opts = null;
      }
      else if (selectType === 'roster' && selectedTypeData.subCats) {
        selectSubCatLabel = 'Team Type';
        select1Opts = null;
        
        selectSubCatOpts = selectedTypeData.subCats.map((item, i) =>
          <option key={i} value={item.name}>{item.title}</option>
        );
      }

  
      console.log('filterSelects', filterSelects);
      
      let data;
      //console.log('gotdata', data)
    }
      
    return (
      <ThemeProvider theme={theme}>
        <div style={{maxWidth: 1260, margin: '0 auto', minHeight: 350}}>
          {hasData &&
            <div>
              <div style={{display: 'flex', flexWrap: 'wrap', justifyContent: 'space-evenly', padding: '6px 24px 6px 24px'}}>
                { false && this.buildSelect(10, 'select-type', 'Type', this.changeSelectType, selectTypeOpts) }
                
                { selectType === 'splits' &&
                  <Fragment>
                    { select1Opts && this.buildSelect(11, 'select-1', 'Metric', this.changeSelect1, select1Opts, state.select1) }
                  </Fragment>
                }
                
                { selectCatOpts && this.buildSelect(12, 'select-cat', 'Category', this.changeSelectCat, selectCatOpts, state.selectType) }
                
                {(winWidth < 768) && <br/>}
                
                { selectSubCatOpts && this.buildSelect(13, 'select-subcat', selectSubCatLabel, this.changeSelectSubCat, selectSubCatOpts, state[selectType].subCats[state.selectSubCat]) }
                
                {filterSelects}
                
                { selectType === 'stats' && select1Opts && this.buildSelect(14, 'select-1', 'Metric', this.changeSelect1, select1Opts) }
              </div>
            
              <div style={{margin: 12, overflow: 'hidden', borderRadius: 10, border: '1px solid #cbccce'}}>
                {(selectType === 'statistics') ? (
                  <TeamStatTable
                    catIdx={state.selectSubCat}
                    catName={state.statistics.subCats[state.selectSubCat].name}
                    teamPlayerData={state.statistics}
                    team={props.team}
                    fetchPlayer={props.fetchPlayer}
                  />
                ) : (selectType === 'schedule') ? (
                  <TeamScheduleTable
                    data={state.schedule}
                    league={props.team.league}
                    teamData={teamData}
                    sport={props.team.sport}
                    showTeam={props.showTeam}
                    showGame={props.showGame}
                    fetchPlayer={props.fetchPlayer}
                  />
                ) : (selectType === 'roster') ? (
                  <TeamRosterTable
                    catIdx={state.selectSubCat}
                    data={state.roster}
                    team={props.team}
                    fetchPlayer={props.fetchPlayer}
                  />
                ) : (selectType === 'contracts') ? (
                  <TeamRosterTable
                    catIdx={state.selectSubCat}
                    data={state.contracts}
                    team={props.team}
                    contracts={props.contracts}
                    fetchPlayer={props.fetchPlayer}
                    onload={this.onload}
                  />
                ) : (selectType === 'depth-chart') ? (
                  <TeamDepthTable
                    catIdx={state.selectSubCat}
                    team={props.team}
                    fetchPlayer={props.fetchPlayer}
                    onload={this.onload}
                  />
                ) : (selectType === 'injuries') ? (
                  <TeamInjuryTable
                    catIdx={state.selectSubCat}
                    team={props.team}
                    fetchPlayer={props.fetchPlayer}
                    onload={this.onload}
                  />
                ) : (selectType === 'transactions') ? (
                  <TeamTransactionTable
                    catIdx={state.selectSubCat}
                    team={props.team}
                    fetchPlayer={props.fetchPlayer}
                    onload={this.onload}
                    setFilters={this.setFilters}
                    initRun={!state.transactions}
                    season={selectedTypeData ? selectedTypeData.filterValues.season : state.leagues[props.team.league].season}
                    month={selectedTypeData ? selectedTypeData.filterValues.month : null}
                  />
                ) : null}
              </div>
            </div>
          }
          
          <Transition in={state.loading || !hasData} timeout={300}>
            {state => (
              <div className="progress-overlay" style={{
                ...defaultStyle,
                ...transitionStyles[state]
              }}>
                <div className="progress-wrap">
                  <CircularProgress size={60} color="secondary" />
                </div>
              </div>
            )}
          </Transition>
            
        </div>
      </ThemeProvider>
    );
  }
}

export default TeamTablePanel;