import React, { Component } from 'react';

import { Iterable, List, fromJS, toJS } from 'immutable';

import { Alert, Pagination } from 'lib/components';


class EditableList extends Component {

	constructor(props) {
		super(props);

		this.renderItem = this.renderItem.bind(this);
		this.renderItemForm = this.renderItemForm.bind(this);
		this.readItems = this.readItems.bind(this);

		this.renderHeader = this.renderHeader.bind(this);
		this.renderFooter = this.renderFooter.bind(this);
		this.renderEmptyList = this.renderEmptyList.bind(this);

		this.saveItem = this.saveItem.bind(this);
		this.deleteItem = this.deleteItem.bind(this);
		this.onItemSaved = this.onItemSaved.bind(this);
		this.onItemDeleted = this.onItemDeleted.bind(this);

		this.showCreateForm = this.showCreateForm.bind(this);
		this.showEditForm = this.showEditForm.bind(this);

		this.hideForm = this.hideForm.bind(this);
		this.renderPagination = this.renderPagination.bind(this);

		this.deleteTitle = this.deleteTitle.bind(this);
		this.deleteMessage = this.deleteMessage.bind(this);
		this.discardTitle = this.discardTitle.bind(this);
		this.discardMessage = this.discardMessage.bind(this);

		this.state = {
			items: [],
			displayForm: false,
			dataIndex: null,
			data: null,
			mode: null
		};
	}


	//TODO
	readItems(props) {
		const pItems = props.items || [];

		//let items = this.state.items;
		//if (pItems != this.state.items) {
		let	items = Iterable.isIterable(pItems) ? pItems : fromJS(pItems);

		if (typeof props.sortFunction === "function") {
			items = props.sortFunction(items);
		}

		let paging = this.state.paging;
		//}
		
		if (props.paged) {
			let defaultPageSize = props.defaultPageSize;
			let pageSize = defaultPageSize || 5;
			let pagesCount = Math.round(items.size / ( pageSize ) + 0.5);

			paging = { ...paging, pagesCount, pageSize };
		}

		this.setState({ items, paging });	
	}


	componentWillMount() {
		this.readItems(this.props);
	}


	componentWillReceiveProps(props) {
		this.readItems(props);
	}


	saveItem(data, opts = {}) {
		let { items, mode, dataIndex } = this.state;

		mode = opts.mode || mode;
		dataIndex = opts.dataIndex || (opts.dataIndex == 0 ? 0 : dataIndex);

		items = mode === 'create' ? items.push(fromJS(data)) : items.set(dataIndex, fromJS(data));

		this.setState({ items, dataIndex: null, displayForm: false, data: null });

		this.onItemSaved(data);

		if (typeof this.props.onItemSaved === "function") {
			this.props.onItemSaved(data);
		}

		let changeHandler = this.props.onChange;
		if (typeof changeHandler === "function") {
			changeHandler(items);
			return;
		}
	}


	deleteItem(index) {
		let { items } = this.state;
		let item = items.get(index);
		if (!item) {
			return;
		}

		let data = item.toJS();

		Alert.alert(this.deleteTitle(data), this.deleteMessage(data), [{ text: this.props.noLabel || 'No', primary: true }, { text: this.props.yesLabel || 'Yes', onPress: () => {
			items = items.delete(index);

			this.onItemDeleted(data);

			if (typeof this.props.onItemDeleted === "function") {
				this.props.onItemDeleted(data);
			}

			let changeHandler = this.props.onChange;
			if (typeof changeHandler === "function") {
				changeHandler(items);
				return;
			}
		}}])
	}


	showCreateForm(index, d) {
		if (this.state.displayForm) {
			Alert.alert(this.discardTitle(this.state.data), this.discardMessage(this.state.data), [{ text: this.props.noLabel || 'No', primary: true }, {text: this.props.yesLabel || 'Yes', onPress: () => {
				let data = fromJS(d || {});
				this.setState({ displayForm: true, data, dataIndex: index, mode: "create" });
			}}]);
		} else {
			let data = fromJS(d || {});
			this.setState({ displayForm: true, data, dataIndex: index, mode: "create" });
		}
	}


	showEditForm(index) {
		if (this.state.displayForm) {
			Alert.alert(this.discardTitle(this.state.data), this.discardMessage(this.state.data), [{ text: this.props.noLabel || 'No', primary: true }, {text: this.props.yesLabel || 'Yes', onPress: () => {
				let items = this.state.items;
				let data = items.get(index);
				this.setState({ displayForm: true, data, dataIndex: index, mode: "edit" });
			}}]);
		} else {
			let items = this.state.items;
			let data = items.get(index);
			this.setState({ displayForm: true, data, dataIndex: index, mode: "edit" });		
		}
	}


	hideForm() {
		this.setState({ displayForm: false, data: null, dataIndex: null })
	}


	renderHeader(disabled) {
		return null;
	}


	renderFooter(disabled) {
		return null;
	}


	renderItemForm(item, key, disabled) {
		return null;
	}


	renderItem(item, key, disabled) {
		return null;
	}

	renderEmptyList() {
		return null;
	}


	renderPagination(paging, onPageChanged) {
		return <Pagination paging={ paging } onPageChanged={ onPageChanged } /> ;
	}


	readPaging(paging, size, defaultPageSize) {
		// paging, onPageChanged, status
		return null;
	}


	render() {
		const { disabled, paged, defaultPageSize } = this.props;
		let { displayForm, items, dataIndex, data, mode, paging } = this.state;
		let rows = [], create = mode !== "edit" && displayForm;

		if (create && dataIndex === 0) {
			rows.push(this.renderItemForm(data, -1, disabled));
		}

		let start = 0;
		let end = items.size;

		if (paged && paging) {
			start = (paging.page || 0) * paging.pageSize;
			end = Math.min(start + paging.pageSize, end);
		}

		for (let i = start; i < end; i++) {
			let item = items.get(i, fromJS({}));
			if (displayForm && !create && i == dataIndex) {
				rows.push(this.renderItemForm(item, i, disabled));
			} else {
				rows.push(this.renderItem(item.toJS(), i, disabled || displayForm));
			}
		}

		if (create && dataIndex < 0) {
			rows.push(this.renderItemForm(data, rows.length, disabled));
		}

		return (
			<div className={ this.props.className }>
				{ this.renderHeader(disabled || displayForm) }
				{ rows.length ? rows : this.renderEmptyList() }
				{ rows.length && paged ? this.renderPagination(paging, (page) => this.setState({ paging: { ...paging, page } })) : null }
				{ this.renderFooter(disabled || displayForm) }
		    </div>
		);
	}


	/* I18N hooks */

	deleteTitle(data) {
		return this.props.deleteMessageLabel || "Delete row";
	}
	
	deleteMessage(data) {
		return this.props.deleteMessageLabel || "Are you sure you want to delete this row?";
	}

	discardTitle(data) {
		return this.props.discardTitleLabel || "Discard changes";
	}
	
	discardMessage(data) {
		return this.props.discardMessageLabel || "Are you sure you want to discard changes?";
	}

	/* other hooks */

	onItemSaved(data) {
		console.warn("onItemSaved", data);
	}

	onItemDeleted(data) {

	}

}

export default EditableList;
