import React, { Component } from 'react';
import {
  FlatList,
  LayoutAnimation,
  StyleSheet,
  View,
} from 'react-native';
import { NavigationActions } from 'react-navigation';
import { connect, Dispatch } from 'react-redux';
import { OfferActions } from '../../actions';
import { Application, Location, Offer, Params, RootState, UserRole } from '../../models';
import { Routes } from '../../navigation';
import { EmptyView, Slider } from '../common';
import { Colors } from '../ui';
import { EmployeeOfferListItem } from './EmployeeOfferListItem';

interface OwnProps {
  applicable?: boolean;
}

interface StateProps {
  loading: boolean;
  role: UserRole;
  offers: Array<Offer>;
  userLocation: Location;
  extraData: {
    applications: Array<Application>;
    activeOffers: {
      [id: string]: Params,
    }
  };
}

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

const INITIAL_RADIUS = 50;
interface DispatchProps {
  onOfferDetailsRequested?: (offer: Offer) => void;
  onApplicationRequested?: (offer: Offer) => void;
}

type Props = OwnProps & StateProps & DispatchProps;

class OfferListComponent extends Component<Props, State> {

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

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

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

  renderItem = ({ item }: { item: Offer }) => {
    const { applications, activeOffers } = this.props.extraData;
    const application = applications.find((app) => app.offerId === item.id);
    return (
      <EmployeeOfferListItem
        status={application && application.status}
        loading={activeOffers[item.id] && activeOffers[item.id].loading}
        offer={item}
        onApplicationRequested={this.props.onApplicationRequested}
        onOfferDetailsRequested={this.props.onOfferDetailsRequested}
      />
    );
  }

  renderEmpty = () => <EmptyView text={'Na razie brak ofert w Twojej okolicy'} style={{ marginTop: 180 }} />;

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

  render() {
    const offers = this.props.offers.filter((o) => this.state.showAll || o.distance / 1000 < this.state.radius);

    return (
      <View style={{ flex: 1 }}>
        <FlatList
          showsVerticalScrollIndicator={false}
          style={styles.container}
          data={offers}
          extraData={this.props.extraData}
          renderItem={this.renderItem}
          keyExtractor={(item) => item.id}
          ListEmptyComponent={this.renderEmpty()}
          ListHeaderComponent={this.renderSlider()}
        />
      </View>
    );
  }
}

const mapStateToProps: (state: RootState) => StateProps =
  (state) => ({
    offers: state.offers.filter((o) => !o.deleted),
    extraData: {
      activeOffers: state.network.offer,
      applications: state.employeeData.applications,
    },
    role: state.user.role,
    userLocation: state.user.body && state.user.body.location,
    loading: false,
  });

const mapDispatchToProps: (dispatch: Dispatch<RootState>) => DispatchProps =
  (dispatch) => ({
    onOfferDetailsRequested: (offer: Offer) => dispatch(NavigationActions.navigate({
      routeName: Routes.OFFER_DETAILS_EMPLOYEE,
      params: { offer },
    })),
    onApplicationRequested: (offer: Offer) => dispatch(OfferActions.newApplicationRequest(offer)),
  });

export const OfferList = connect(mapStateToProps, mapDispatchToProps)(OfferListComponent);

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});
