import React, { Component } from 'react';
import {
  Alert,
  Image,
  ScrollView,
  StyleSheet,
  TouchableNativeFeedback,
  UIManager,
  View,
} from 'react-native';
import { Badge, Icon, Text } from 'react-native-elements';
import { NavigationScreenProps } from 'react-navigation';
import { connect, Dispatch } from 'react-redux';
import { NavActions } from '../../actions';
import { OfferActions } from '../../actions';
import { ApplicationData, ApplicationStatus, Offer, RootState } from '../../models';
import { RelativeTimestamp } from '../common';
import { Colors, Header } from '../ui';
import { EmployerOfferApplication } from './EmployerOfferApplication';

interface OwnProps extends NavigationScreenProps<{ offerId: string }> {
}

interface DispatchProps {
  onEmployeeDetailsRequested: (employeeId: string) => any;
  onOfferEditRequested: (offer: Offer) => any;
  onOfferDeleteRequested: (offer: Offer) => any;
  onApplicationAccepted: (application: ApplicationData) => any;
  onApplicationRejected: (application: ApplicationData) => any;
}

interface StateProps {
  offer: Offer;
  applications: Array<ApplicationData>;
}

type Props = OwnProps & DispatchProps & StateProps;

class OfferDetailsComponent extends Component<Props> {

  constructor(props: Props) {
    super(props);
    // tslint:disable:no-unused-expression
    UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);
  }

  edit = () => this.props.onOfferEditRequested(this.props.offer);

  delete = () => {
    Alert.alert(
      'Potwierdź',
      'Czy na pewno chcesz usunąć to ogłoszenie?',
      [
        { text: 'Anuluj', onPress: null, style: 'cancel' },
        { text: 'Tak', onPress: () => this.props.onOfferDeleteRequested(this.props.offer) },
      ],
      { cancelable: false },
    );
  }

  renderLocation() {
    const offer = this.props.offer;

    return (
      <View>
        <Text style={styles.smallText}>
          {offer.location.name}
        </Text>
        <Text style={styles.smallText}>
          {offer.location.address}
        </Text>
      </View>
    );
  }

  renderApplications() {
    const {
      onEmployeeDetailsRequested,
      onApplicationAccepted,
      onApplicationRejected,
      applications,
    } = this.props;
    return (
      <View style={{ marginBottom: 20, backgroundColor: 'transparent' }}>
        <Text style={styles.applicationListTitle}>
          Aplikacje
        </Text>
        {this.renderStats()}
        {
          applications.map((application) => (
            <EmployerOfferApplication
              key={application.id}
              applicationData={application}
              onAccepted={() => onApplicationAccepted(application)}
              onRejected={() => onApplicationRejected(application)}
              onEmployeeDetailsRequested={() => onEmployeeDetailsRequested(application.employeeId)}
            />
          ))
        }
      </View>
    );
  }

  renderOfferInfo(offer: Offer) {
    return (
      <View style={styles.header}>
        <View style={{ flex: 3 }}>
          <RelativeTimestamp
            timestamp={offer.dateEnd}
            style={styles.smallText}
            prefix={{
              past: 'Oferta wygasła',
              future: 'Oferta wygasa',
            }}
          />
          <Text style={styles.smallText}>Ilość miejsc: {offer.freeSlots}{'/'}{offer.slots}</Text>
          {offer.location && this.renderLocation()}
        </View>
        <View style={{ flex: 1 }}>
          <Image source={{ uri: offer.image }} style={styles.image} />
        </View>
      </View>
    );
  }

  renderStats() {
    const { applications } = this.props;
    const accepted = applications.filter(({ status }) => status === ApplicationStatus.ACCEPTED);
    const pending = applications.filter(({ status }) => status === ApplicationStatus.PENDING);
    const rejected = applications.filter(({ status }) => status === ApplicationStatus.REJECTED);
    return (
      <ScrollView horizontal={true} showsHorizontalScrollIndicator={false}>
        <View style={styles.badges}>
          <Badge
            textStyle={{ fontSize: 11 }}
            value={`Wszystkie: ${applications.length}`}
            containerStyle={[styles.badge, { backgroundColor: 'gray' }]}
          />
          {
            pending.length > 0 && (
              <Badge
                textStyle={{ fontSize: 11 }}
                value={`Oczekujące: ${pending.length}`}
                containerStyle={[styles.badge, { backgroundColor: 'rgb(30,139,255)' }]}
              />
            )
          }
          {
            accepted.length > 0 && (
              <Badge
                textStyle={{ fontSize: 11 }}
                value={`Zaakceptowane: ${accepted.length}`}
                containerStyle={[styles.badge, { backgroundColor: Colors.employee.offerAccepted }]}
              />
            )
          }
          {
            rejected.length > 0 && (
              <Badge
                textStyle={{ fontSize: 11 }}
                value={`Odrzucone: ${rejected.length}`}
                containerStyle={[styles.badge, { backgroundColor: Colors.employee.offerRejected }]}
              />
            )
          }
        </View>
      </ScrollView>
    );
  }

  renderActionRow() {
    return (
      <View style={{ flexDirection: 'row-reverse' }}>
        <TouchableNativeFeedback onPress={this.delete}>
          <View style={{ padding: 8, flexDirection: 'row', alignItems: 'center' }}>
            <Text style={{ margin: 3, color: 'red' }}>
              Usuń
            </Text>
            <Icon name='delete' size={16} color={'red'} />
          </View>
        </TouchableNativeFeedback>
        <TouchableNativeFeedback onPress={this.edit}>
          <View style={{ padding: 8, flexDirection: 'row', alignItems: 'center' }}>
            <Text style={{ margin: 3 }}>
              Edytuj
            </Text>
            <Icon name='edit' size={16} color={'gray'} />
          </View>
        </TouchableNativeFeedback>
      </View>
    );
  }

  render() {
    const offer = this.props.offer;
    return !!offer && (
      <View style={styles.container}>
        <Header title='Szczegóły oferty' />
        <ScrollView style={{ flex: 1 }}>
          <View style={styles.offer}>
            {this.renderActionRow()}
            <Text style={styles.title}>{offer.title}</Text>
            {this.renderOfferInfo(offer)}
            <Text style={{ flex: 1 }}>{offer.description}</Text>
          </View>
          {this.renderApplications()}
        </ScrollView>
      </View>
    );
  }
}

const mapStateToProps: (state: RootState, ownProps: OwnProps) => StateProps =
  (state, ownProps) => {
    const offerId = ownProps.navigation.state.params.offerId;
    return {
      offer: state.offers.find((offer) => offer.id === offerId),
      applications: state.employerData.applications.filter((application) => application.offerId === offerId),
    };
  };

const mapDispatchToProps: (dispatch: Dispatch<RootState>) => DispatchProps =
  (dispatch) => ({
    onOfferEditRequested: (offer: Offer) => dispatch(NavActions.NavigateToOfferEditDetails(offer)),
    onOfferDeleteRequested: (offer: Offer) => dispatch(OfferActions.DeleteOfferRequested(offer)),
    onEmployeeDetailsRequested: (employeeId) => dispatch(NavActions.navigateToEmployeeDetails(employeeId)),
    onApplicationAccepted: (application) => dispatch(OfferActions.applicationAcceptedRequested(application)),
    onApplicationRejected: (application) => dispatch(OfferActions.applicationRejectedRequested(application)),
  });

export const EmployerOfferDetails = connect(mapStateToProps, mapDispatchToProps)(OfferDetailsComponent);

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  badges: {
    flexDirection: 'row',
    justifyContent: 'flex-start',
    padding: 8,
  },
  badge: {
    margin: 4,
  },
  offer: {
    padding: 16,
    backgroundColor: 'white',
  },
  applicationListTitle: {
    alignSelf: 'flex-start',
    marginTop: 12,
    marginHorizontal: 12,
    fontSize: 16,
    fontWeight: 'bold',
  },
  offerTitle: {
    fontWeight: 'bold',
    textAlign: 'center',
    marginBottom: 8,
    fontSize: 16,
  },
  title: {
    fontWeight: 'bold',
    fontSize: 14,
    marginVertical: 8,
  },
  header: {
    flex: 1,
    marginBottom: 4,
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  smallText: {
    fontSize: 11,
  },
  image: {
    marginLeft: 4,
    height: 72,
    width: 72,
    borderRadius: 2,
  },
  emptyList: {
    fontSize: 14,
    alignSelf: 'center',
    padding: 20,
  },
  applicationsHeader: {
    backgroundColor: 'white',

    justifyContent: 'center',
    alignItems: 'center',
  },
});
