import React from "react";
import {
  ActivityIndicator,
  StyleSheet,
  View,
  StatusBar,
  Text,
  TouchableOpacity,
  RefreshControl,
} from "react-native";
import themeColors from '../components/themeColors';
import EntypoIcon from "react-native-vector-icons/Entypo";
import AntDesignIcon from "react-native-vector-icons/AntDesign";
import FaIcon from "react-native-vector-icons/FontAwesome5";
import ImageHeader from "../components/ImageHeader";
import { SwipeListView } from 'react-native-swipe-list-view';
import { connect } from 'react-redux';
import request from '../utility/PromiseRequest';
import DataAnalysis from '../data_processing/DataAnalysis';
import * as msgpack from 'msgpack-lite';
import { timeSince } from '../utility/TimeUtils';
import XMLParser from 'react-xml-parser';

function SessionCard(props) {
  return (
    <View style={sessionCardStyles.card}>
      <View>
        <Text style={sessionCardStyles.firstLineText}>{props.textFirstLine}</Text>
      </View>

      <View style={sessionCardStyles.secondLine}>
        <View style={sessionCardStyles.iconTextPair}>
          <FaIcon name="stopwatch" style={sessionCardStyles.icon} />
          <Text style={sessionCardStyles.secondLineText}>{props.activeTime}</Text>
        </View>
        <View style={sessionCardStyles.iconTextPair}>
          <EntypoIcon name="ruler" style={sessionCardStyles.icon} />
          <Text style={sessionCardStyles.secondLineText}>{props.momentum}</Text>
        </View>
        <View style={sessionCardStyles.iconTextPair}>
          <AntDesignIcon name="retweet" style={sessionCardStyles.icon} />
          <Text style={sessionCardStyles.secondLineText}>{props.laps}</Text>
        </View>
      </View>
    </View>
  )
}

function SessionCardBehindSwipe(props) {
  return (
    <View style={sessionCardStyles.rowBack}>
      <TouchableOpacity
        style={sessionCardStyles.deleteButton}
        onPress={props.onDelete}
      >
        <Text style={{ fontSize: 18, color: "white" }}>Löschen</Text>
      </TouchableOpacity>
    </View>
  );
}

const sessionCardStyles = StyleSheet.create({
  card: {
    backgroundColor: "#559ac8",
    borderRadius: 12,
    height: 100,
    maxHeight: 100,
    flex: 1,
    flexDirection: "column",
    justifyContent: "space-around",
    padding: 10,
    margin: 10,
    paddingLeft: 20,
  },
  firstLineText: {
    color: "white",
    fontSize: 22
  },
  iconTextPair: {
    maxWidth: 100,
    flex: 1,
    flexDirection: "row",
    alignItems: "center",
  },
  secondLine: {
    flex: 1,
    justifyContent: "space-between",
    alignContent: "center",
    flexDirection: "row",
    maxHeight: 30,
    marginTop: 14,
  },
  icon: {
    fontSize: 30,
    color: "white",
    paddingRight: 10,
  },
  secondLineText: {
    color: "white",
    fontSize: 18,
  },
  spacerHidden: {
    flex: 1,
    color: "black",
  },
  rowBack: {
    alignItems: 'center',
    backgroundColor: themeColors['ALIZARIN'],
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'space-between',
    height: 100,
    padding: 10,
    margin: 10,
    paddingLeft: 20,
    borderRadius: 12,
  },
  deleteButton: {
    alignItems: 'center',
    bottom: 0,
    justifyContent: 'center',
    position: 'absolute',
    backgroundColor: themeColors['ALIZARIN'],
    top: 0,
    width: 150,
    right: 0,
    borderTopRightRadius: 12,
    borderBottomRightRadius: 12,
  },
})

// ---------------------------------------------------------------------------------------------

function parsePropfind(text) {
  const parser = new XMLParser();
  const xmlDoc = parser.parseFromString(text);

  //const parser = new DOMParser();
  //const xmlDoc = parser.parseFromString(text, "text/xml");

  const responses = xmlDoc.getElementsByTagName("D:response");
  let result = [];
  for (let i = 0; i < responses.length; ++i) {
    const e = responses[i];
    const name = e.getElementsByTagName("D:href")[0].value;
    const size = e.getElementsByTagName("D:getcontentlength")[0].value;
    result.push({
      name: name,
      size: parseInt(size),
      startTime: parseInt(name.split(".")[0])
    });
  }
  return result;
}

const msgpackCodec = msgpack.createCodec();
msgpackCodec.addExtUnpacker(205, function (byteArr) {
  const buffer = byteArr.buffer.slice(byteArr.byteOffset, byteArr.byteLength + byteArr.byteOffset);
  const result = new Int16Array(buffer);
  return result;
});


async function getSessionDetails(swimTrackerHost, sessionFileName) {
  const url = "http://" + swimTrackerHost + "/webdav/" + sessionFileName;
  const arrayBuffer = await request({ url: url, responseType: 'arraybuffer' });
  return msgpack.decode(new Uint8Array(arrayBuffer), { codec: msgpackCodec });
}

async function getSessionsFromDevice(swimTrackerHost) {
  const data = await request({ url: "http://" + swimTrackerHost + "/webdav/", method: "PROPFIND" });
  return parsePropfind(data);
}

async function getFullData(swimTrackerHost, analysisSettings) {
  const parsed = await getSessionsFromDevice(swimTrackerHost);
  for (let index = 0; index < parsed.length; index++) {
    const e = parsed[index];
    const sessionDetails = await getSessionDetails(swimTrackerHost, e.name);
    e.values = sessionDetails.values;
    const da = new DataAnalysis();
    e.analysis = da.analyze(analysisSettings, e.startTime, e.values);
  }
  return parsed;
}

// ---------------------------------------------------------------------------------------------

class LastSessionsView extends React.Component {

  constructor() {
    super();
    this.state = { sessions: null, refreshing: false };
  }

  componentDidMount() {
    getFullData(this.props.swimTrackerHost, this.props.analysisSettings).then(
      e => this.setState({ sessions: e })
    );
  }

  render() {
    const deleteSession = async sessionFileName => {
      this.setState({ sessions: null });
      await request({ url: "http://" + this.props.swimTrackerHost + "/webdav/" + sessionFileName, method: "DELETE" });
      this.setState({ sessions: await getFullData(this.props.swimTrackerHost, this.props.analysisSettings) });
    };

    const onRefresh = async () => {
      this.setState({ refreshing: true });
      const newSessions = await getFullData(this.props.swimTrackerHost, this.props.analysisSettings);
      this.setState({ sessions: newSessions, refreshing: false });
    };

    let innerView;
    if (this.state.sessions) {
      innerView = <SwipeListView
        refreshControl={<RefreshControl refreshing={this.state.refreshing} onRefresh={onRefresh} /> }
        style={{ width: "100%" }}
        keyExtractor={item => item.startTime.toString()}
        disableRightSwipe={true}
        data={this.state.sessions.reverse()}
        renderItem={(data, rowMap) => (
          <SessionCard
            textFirstLine={timeSince(data.item.startTime)}
            laps={(data.item.analysis.peaks.size / this.props.peaksPerLap).toFixed(1)}
            momentum={Math.trunc(data.item.analysis.totalMomentum * this.props.kgFactor / 10 / 60)}
            activeTime={data.item.analysis.activeTime} />
        )}
        renderHiddenItem={(data, rowMap) => <SessionCardBehindSwipe onDelete={() => { deleteSession(data.item.name) }} />}
        leftOpenValue={0}
        rightOpenValue={-120}
        stopRightSwipe={-145}
      />
    }
    else {
      innerView = (
        <View style={{
          flex: 1,
          justifyContent: "center",
          flexDirection: "row",
          justifyContent: "space-around",
        }}>
          <ActivityIndicator size="large" color="#aaa"></ActivityIndicator>
        </View>
      );
    }

    return (
      <View style={{ flex: 1 }}>
        <StatusBar hidden={true} />
        <View style={{ flex: 1 }}>
          <ImageHeader
            text="LETZTE SESSIONS"
            navigation={this.props.navigation}
            image={require("../assets/swimmer.jpg")}
          />
          <View style={{ flex: 1, backgroundColor: themeColors["BELIZE HOLE"] }}>
            {innerView}
          </View>
        </View>
      </View>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    swimTrackerHost: state.settings.swimTrackerHost,
    analysisSettings: state.settings.analysis,
    kgFactor: state.settings.analysis.kgFactor,
    peaksPerLap: state.settings.analysis.peaksPerLap,
  };
};
export default connect(mapStateToProps)(LastSessionsView);

