import React from 'react';
import {withNamespaces} from 'react-i18next';

import Loading from "../../component/Loading";

import {withTheme, injectSheet} from '../../lib/theme';
import {ApiRequest, GET, PUT} from '../../lib/ApiRequest';

import ArticleDetailHead from './ArticleDetailHead';
import ArticleDetailHelp from './ArticleDetailHelp';
import ArticleDetailMeta from './ArticleDetailMeta';
import ArticleDetailMainText from './ArticleDetailMainText';
import ArticleDetailDocTree from './ArticleDetailDocTree';
import ArticleDetailSavingChart from './ArticleDetailSavingChart';

const theming = theme => ({
    button: {
        fontSize: '0.875rem',
        background: 'none',
        padding: theme.gutter.base + 'px ' + theme.gutter.base * 2 + 'px',
        '&:first-child': {
            paddingLeft: 0,
        },
        '&:last-child': {
            paddingRight: 0,
        }
    },
    headWrapper: {},
    subTitle: {
        margin: '-12px 0 6px 0',
    }
});

const styling = {
    button: theme => ({
        color: theme.linkColor
    }),
};

const initialState = {
    data: {},
    loaded: false,
    openMeta: false,
    openHelp: false,
    cacheid: false,
    saving: {
        meta: false,
        mainText: false,
        docTree: false,
    },
};

class ArticleDetail extends React.Component {

    state = initialState;

    componentWillUnmount() {
        this.setState(initialState);
    }

    //
    // Api Fetch and Push

    createUpdatedSaving(name, val) {
        const saving = {...this.state.saving};
        saving[name] = val;
        return saving;
    }

    fetch() {
        this.setState({loaded: 'progress'});
        (new ApiRequest('api', GET, 'content/article/' + this.props.match.params.section + '/' + this.props.match.params.article))
            .debug(true)
            .header({})
            .exec()
            .then((res) => {
                if(res && res.data) {
                    if(res.data) {
                        this.setState({
                            data: res.data,
                            loaded: true,
                            cacheid: '#' + this.props.match.params.section + '##' + this.props.match.params.article + '#'
                        });
                    }
                    if(res.data.error) {
                        this.setState({
                            loaded: 'error'
                        });
                    }
                } else {
                    this.setState({
                        loaded: 'error'
                    });
                }
            })
            .catch(() => {
                this.setState({
                    loaded: 'error'
                });
            });
    }

    pushMeta = (meta) => {
        this.setState({saving: this.createUpdatedSaving('meta', 'progress')});
        (new ApiRequest('api', PUT, 'content/article/' + this.props.match.params.section + '/' + this.props.match.params.article, {meta: meta}))
            .debug(true)
            .header({})
            .exec()
            .then((res) => {
                if(res && res.data) {
                    if(res.data) {
                        this.setState({saving: this.createUpdatedSaving('meta', 'success')});

                        setTimeout(() => {
                            this.setState({saving: this.createUpdatedSaving('meta', false)});
                        }, 4000);
                    }
                    if(res.data.error) {
                        this.setState({saving: this.createUpdatedSaving('meta', 'error')});
                    }
                } else {
                    this.setState({saving: this.createUpdatedSaving('meta', 'error')});
                }
            })
            .catch(() => {
                this.setState({saving: this.createUpdatedSaving('meta', 'error')});
            });
    };

    pushMainText = (text) => {
        this.setState({saving: this.createUpdatedSaving('mainText', 'progress')});
        (new ApiRequest('api', PUT, 'content/article/' + this.props.match.params.section + '/' + this.props.match.params.article, {mainText: text}))
            .debug(true)
            .header({})
            .exec()
            .then((res) => {
                if(res && res.data) {
                    if(res.data) {
                        this.setState({saving: this.createUpdatedSaving('mainText', 'success')});

                        setTimeout(() => {
                            this.setState({saving: this.createUpdatedSaving('mainText', false)});
                        }, 4000);
                    }
                    if(res.data.error) {
                        this.setState({saving: this.createUpdatedSaving('mainText', 'error')});
                    }
                } else {
                    this.setState({saving: this.createUpdatedSaving('mainText', 'error')});
                }
            })
            .catch(() => {
                this.setState({saving: this.createUpdatedSaving('mainText', 'error')});
            });
    };

    pushDocTree = (tree) => {
        this.setState({saving: this.createUpdatedSaving('docTree', 'progress')});
        (new ApiRequest('api', PUT, 'content/article/' + this.props.match.params.section + '/' + this.props.match.params.article, {docTree: tree}))
            .debug(true)
            .header({})
            .exec()
            .then((res) => {
                if(res && res.data) {
                    if(res.data) {
                        this.setState({saving: this.createUpdatedSaving('docTree', 'success')});

                        setTimeout(() => {
                            this.setState({saving: this.createUpdatedSaving('docTree', false)});
                        }, 4000);
                    }
                    if(res.data.error) {
                        this.setState({saving: this.createUpdatedSaving('docTree', 'error')});
                    }
                } else {
                    this.setState({saving: this.createUpdatedSaving('docTree', 'error')});
                }
            })
            .catch(() => {
                this.setState({saving: this.createUpdatedSaving('docTree', 'error')});
            });
    };

    //
    // Open Toggles

    openMeta = () => {
        this.setState({
            openMeta: !this.state.openMeta
        });
    };

    openHelp = () => {
        this.setState({
            openMeta: !this.state.openMeta
        });
    };

    //
    // Default Lifecycles

    componentDidUpdate(prevProps) {
        if(prevProps.match.params.section !== this.props.match.params.section ||
            prevProps.match.params.article !== this.props.match.params.article) {
            this.fetch();
        }
    }

    componentDidMount() {
        this.fetch();
    }

    render() {
        const {t, theme, classes, match} = this.props;

        const section = match.params.section;
        const article = match.params.article;

        return (
            <React.Fragment>
                {true !== this.state.loaded ? <h1>{t('title')}</h1> : null}
                {
                    true === this.state.loaded ?
                        (<React.Fragment>

                            <ArticleDetailSavingChart saving={this.state.saving}/>

                            <div className={classes.headWrapper}>
                                <h1>{t('title')}</h1>
                                {this.state.data && this.state.data.id ? <h2 className={classes.subTitle}>{this.state.data.id}</h2> : null}

                                <ArticleDetailHead data={this.state.data}/>

                                <div className={'nav'}>
                                    <button onClick={this.openMeta} className={classes.button} style={styling.button(theme)}>{this.state.openMeta ? t('nav.editmeta-hide') : t('nav.editmeta')}</button>
                                    {/*<button onClick={this.openHelp} className={classes.button} style={styling.button(theme)}>{t('nav.openhelp')}</button>*/}
                                </div>
                            </div>

                            <ArticleDetailHelp open={this.state.openHelp}
                                               toggle={this.openHelp}
                            />

                            <ArticleDetailMeta meta={this.state.data.meta}
                                               open={this.state.openMeta}
                                               section={section}
                                               article={article}
                                               cacheid={this.state.cacheid}
                                               saveFn={this.pushMeta}
                                               saving={this.state.saving.meta}
                            />

                            <ArticleDetailMainText content={this.state.data.mainText}
                                                   section={section}
                                                   article={article}
                                                   saveFn={this.pushMainText}
                                                   saving={this.state.saving.mainText}
                            />

                            {this.state.data && this.state.data.meta && this.state.data.meta['_doc-tree'] && this.state.data.meta['_page-type'] ?
                                <ArticleDetailDocTree section={section}
                                                      article={article}
                                                      meta={this.state.data.meta}
                                                      doctree={this.state.data['docTree']}
                                                      saveFn={this.pushDocTree}
                                                      saving={this.state.saving.docTree}
                                /> :
                                t('article-without-doctree')}

                        </React.Fragment>) :
                        ('progress' === this.state.loaded || 'error' === this.state.loaded ?
                            <Loading style={{
                                wrapper: {margin: 0},
                                item: ('error' === this.state.loaded ? {borderColor: this.props.theme.errorColor} : {}),
                            }}/> :
                            null)
                }
            </React.Fragment>
        )
    };
}

export default withNamespaces('page--content-article')(withTheme(injectSheet(theming)(ArticleDetail)));