import { getDistance } from 'geolib';
import React, { Component } from 'react';
import {
  FlatList,
  LayoutAnimation,
  StyleSheet,
  View,
} from 'react-native';
import { connect, Dispatch } from 'react-redux';
import { NavActions } from '../../actions';
import { EmptyView, Slider } from '../../components/common';
import { EmployeeListItem } from '../../components/employer';
import { Colors } from '../../components/ui';
import { Location, MapOfEmployees, RootState, UserBody } from '../../models';
import { RenderErrorView } from '../RenderError';

interface OwnProps {
  createNewOffer: () => void;
}

interface StateProps {
  employees: MapOfEmployees;
  userLocation: Location;
}

interface State {
  radius: number;
  showAll: boolean;
  error: boolean;
}

const INITIAL_RADIUS = 50;

interface DispatchProps {
  onEmployeeDetailsRequested: (employeeId: string) => void;
}
type Props = OwnProps & StateProps & DispatchProps;

class EmployeeListComponent extends Component<Props, State> {

  state = {
    radius: this.props.userLocation && INITIAL_RADIUS || 100,
    showAll: !this.props.userLocation,
    error: false,
  };

  onItemSelected = (item: UserBody) => this.props.onEmployeeDetailsRequested(item.id);

  renderItem = ({ item }: { item: UserBody & { distance: number } }) => (
    <EmployeeListItem
      employee={item}
      onSelected={() => this.onItemSelected(item)}
    />
  )

  updateDistance = (radius: number) => {
    this.setState({
      radius,
      showAll: radius === 100,
    });
  }

  componentDidCatch(error) {
    this.setState({ error: true });
  }

  componentWillUpdate() {
    LayoutAnimation.configureNext({
      duration: 300,
      update: {
        type: LayoutAnimation.Types.linear,
        property: LayoutAnimation.Properties.opacity,
      },
    });
  }

  renderEmpty = () => <EmptyView text={'Nie ma nikogo w pobliżu'} style={{ marginTop: 180 }} />;

  renderSlider = () => (
    <Slider
      disabled={!this.props.userLocation}
      distance={this.state.radius}
      onChange={this.updateDistance}
      sliderPrimaryColor={Colors.employer.primary}
      sliderSecondaryColor={'#f48b4b'}
    />
  )

  render() {
    if (this.state.error) return <RenderErrorView />;
    const employees = Object.keys(this.props.employees)
      .map((key) => this.props.employees[key])
      .map((employee) => ({
        ...employee,
        distance: this.props.userLocation && employee.location &&
          getDistance(this.props.userLocation, employee.location, 1000, 0),
      }))
      .filter((employee) => this.state.showAll || employee.distance / 1000 < this.state.radius);
    return (
      <View style={{ flex: 1 }}>
        <FlatList
          showsVerticalScrollIndicator={false}
          ListHeaderComponent={this.renderSlider()}
          style={styles.container}
          data={employees}
          renderItem={this.renderItem}
          ListEmptyComponent={this.renderEmpty()}
          keyExtractor={(item) => item.id}
        />
      </View>
    );
  }
}

const mapStateToProps: (state: RootState) => StateProps =
  (state) => ({
    employees: state.employerData.employees,
    userLocation: state.user.body && state.user.body.location,
  });

const mapDispatchToProps: (dispatch: Dispatch<RootState>) => DispatchProps =
  (dispatch) => ({
    onEmployeeDetailsRequested: (employeeId) => dispatch(NavActions.navigateToEmployeeDetails(employeeId)),
  });

export const EmployeeList = connect(mapStateToProps, mapDispatchToProps)(EmployeeListComponent);

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  sliderArea: {
    padding: 16,
    backgroundColor: Colors.employer.primary,
  },
});
