import React, { Component } from 'react';
import {
  Dimensions,
  Image,
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import { Icon } from 'react-native-elements';
import { NavigationScreenProps } from 'react-navigation';
import { connect, Dispatch } from 'react-redux';
import { ChatActions, NavActions, OfferActions } from '../../actions';
import { ApplicationStatus, Offer, RootState } from '../../models';
import { RenderErrorView } from '../../scenes/RenderError';
import { getOfferStatus } from '../../utils/Formatter';
import { ApplicationStatusBar, DistanceIndicator, RelativeTimestamp } from '../common/';
import { Button, Card, Header } from '../ui';

interface OwnProps extends NavigationScreenProps<{ offer: Offer }> {
}

interface StateProps {
  loading: boolean;
  offer: Offer;
  status?: ApplicationStatus;
}

interface DispatchProps {
  onEmployerProfileRequested: (employerId: string) => void;
  onApplicationRequested?: (offer: Offer) => void;
  onChatRequested: (employerId: string, employerName: string) => void;
}

type Props = OwnProps & DispatchProps & StateProps;

class OfferListComponent extends Component<Props, { error: boolean }> {

  state = { error: false };

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

  renderEmployer(offer: Offer) {
    const { ownerName } = offer;
    return (
      <View style={styles.employerRow}>
        <TouchableOpacity onPress={() => this.props.onEmployerProfileRequested(offer.ownerId)}>
          <View style={{ flexDirection: 'row', alignItems: 'center', paddingVertical: 4 }}>
            <Icon
              name='person'
              color='gray'
              size={16}
              containerStyle={{ marginRight: 4 }}
            />
            <Text style={{ fontWeight: 'bold', color: 'gray' }}>
              {ownerName}
            </Text>
          </View>
        </TouchableOpacity>
        {
          this.props.status !== ApplicationStatus.ACCEPTED && (
            <Icon
              name='chat'
              color='gray'
              size={15}
              onPress={() => this.props.onChatRequested(offer.ownerId, offer.ownerName)}
            />
          )
        }
      </View>
    );
  }

  renderStatus() {
    return this.props.status && getOfferStatus(this.props.status) || 'Aplikuj na tę ofertę';
  }

  renderApplicationButton(offer: Offer) {
    const { loading, onApplicationRequested } = this.props;
    const title = loading ? '' : 'Aplikuj';
    return (
      <Button
        loading={loading}
        disabled={loading}
        containerViewStyle={styles.buttonContainer}
        buttonStyle={styles.button}
        title={title}
        onPress={() => onApplicationRequested(offer)}
      />
    );
  }

  renderChatButton(offer: Offer) {
    const { onChatRequested } = this.props;
    return this.props.status === ApplicationStatus.ACCEPTED && (
      <Button
        containerViewStyle={styles.buttonContainer}
        buttonStyle={styles.button}
        title={'Porozmawiaj z pracodawcą'}
        onPress={() => onChatRequested(offer.ownerId, offer.ownerName)}
      />
    );
  }

  renderInfo(offer: Offer) {
    return (
      <View style={styles.info}>
        <Text style={styles.offerTitle}>
          {offer.title}
        </Text>
        {this.renderEmployer(offer)}
        {!!offer.distance && <DistanceIndicator distance={offer.distance} style={{ marginTop: 4 }} />}
        {!!offer.location && this.renderLocation(offer)}
        <RelativeTimestamp
          timestamp={offer.dateEnd}
          style={styles.smallText}
          prefix={{
            past: 'Oferta wygasła',
            future: 'Oferta wygasa',
          }}
        />
      </View>
    );
  }

  renderDescription(offer: Offer) {
    return (
      <View style={styles.description}>
        <Text>
          {offer.description}
        </Text>
      </View>
    );
  }

  renderButton(offer: Offer) {
    switch (this.props.status) {
      case ApplicationStatus.ACCEPTED:
        return this.renderChatButton(offer);
      case undefined:
        return this.renderApplicationButton(offer);
      default:
        return null;
    }
  }

  renderContent() {
    const offer = this.props.offer;
    return (
      <View>
        <Card style={{ padding: 0 }}>
          <View style={{ padding: 12 }}>
            {this.renderInfo(offer)}
            {this.renderDescription(offer)}
            {this.renderButton(offer)}
          </View>
          <ApplicationStatusBar status={this.props.status} />
        </Card>
      </View>
    );
  }

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

    return (
      <View style={{ flex: 1 }}>
        <Image
          resizeMode='cover'
          source={{ uri: offer.image }}
          style={styles.image}
        />
      </View>

    );
  }

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

  renderDeleted() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text style={{ textAlign: 'center' }}>
          Oferta została usunięta
        </Text>
      </View>
    );
  }

  renderWithoutError() {
    const offer = this.props.offer;
    return offer.deleted ? this.renderDeleted() : (
      <ScrollView>
        {this.renderHeader()}
        {this.renderContent()}
      </ScrollView>
    );
  }

  render() {
    const error = this.state.error;
    return (
      <View style={{ flex: 1 }}>
        <Header title={'Szczegoły oferty'} />
        {error && <RenderErrorView />}
        {!error && this.renderWithoutError()}
      </View>
    );
  }
}

const mapStateToProps: (state: RootState, ownProps: OwnProps) => StateProps =
  (state, ownProps) => {
    const offerId = ownProps.navigation.state.params.offer.id;
    const activeOffers = state.network.offer;
    const offer = state.offers.find((o) => o.id === offerId);
    const application = offer && state.employeeData.applications.find((app) => app.offerId === offer.id);
    return {
      offer,
      loading: !offer || activeOffers[offer.id] && activeOffers[offer.id].loading,
      status: application && application.status,
    };
  };
const mapDispatchToProps: (dispatch: Dispatch<RootState>) => DispatchProps =
  (dispatch) => ({
    onEmployerProfileRequested: (employerId: string) =>
      dispatch(NavActions.navigateToEmployerDetails(employerId)),
    onApplicationRequested: (offer: Offer) => dispatch(OfferActions.newApplicationRequest(offer)),
    onChatRequested: (employerId, employerName) => dispatch(ChatActions.openChatRoomRequest(employerId, employerName)),
  });

export const EmployeeOfferDetails = connect(mapStateToProps, mapDispatchToProps)(OfferListComponent);
const win = Dimensions.get('window');

const styles = StyleSheet.create({
  topRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  employerRow: {
    flex: 1,
    justifyContent: 'space-between',
    alignItems: 'center',
    flexDirection: 'row',
  },
  offerTitle: {
    fontWeight: 'bold',
    textAlign: 'center',
    marginBottom: 8,
    fontSize: 16,
  },
  smallText: {
    fontSize: 11,
  },
  description: {
    marginTop: 16,
  },
  info: {
    marginRight: 4,
  },
  image: {
    alignSelf: 'center',
    width: win.width,
    height: 250,
  },
  author: {
    paddingVertical: 4,
  },
  date: {
    paddingVertical: 4,
  },
  button: {
    marginTop: 12,
  },
  buttonContainer: {
    marginTop: 8,
    marginLeft: 0,
    marginRight: 0,
  },
});
