import React from 'react';
import { Row, Col, Button } from 'neatui';
import xhr from 'SERVICE/xhr';
import './index.scss';
import BaseComponent from 'COMPONENT/common/BaseComponent';
import { withRouter } from 'react-router-dom';
import { success, error } from 'UTIL/notification';
import { isArray, getSearchParams, parseData2Url, parseFixedParameter } from 'UTIL/util';
import SearchBar from 'COMPONENT/container/SearchBar';
import moment from 'moment';
import 'moment/locale/zh-cn';
import projectConfig from 'CONFIG/projectConfig.json';

moment.locale('zh-cn');
const THOUSAND = 1000;

const localHost = projectConfig.localhost || [];
localHost.push('localhost');

class Detaillist extends BaseComponent {
    constructor(props, context) {
        super(props, context);
        this.env = localHost.indexOf(window.location.hostname) > -1 ? 'local.' : '';
        const { getInstance } = props;
        if (typeof getInstance === 'function') {
            getInstance(this);
        }
        this.searchParams = getSearchParams();
        this.config = this.props.config;
        this.notInit = (this.config.basic && this.config.basic.notInit) || false;
        this.state = {
            searchForm: {},
            detailData: {},
            p2c: false
        };
    }

    componentDidMount() {
        if (!this.state.p2c && !this.notInit) this.fetchDataHandler();
    }

    parentToChildren = (params) => {
        this.setState({
            p2c: true
        }, () => {
            this.fetchDataHandler(JSON.parse(JSON.stringify(params || {})));
        });
    }

    resetHandler = () => {
        this.setState({
            detailData: {},
            p2c: false
        });
    }

    getSearchData = (url, params) => {
        const mine = this;
        const { searchForm } = mine.props;
        
        let searchParams = mine.searchParams || {};
        if (mine.config.basic.isNeedLocationSearch && isArray(mine.config.basic.isNeedLocationSearch)) {
            searchParams = {};
            for (let i = 0; i < mine.config.basic.isNeedLocationSearch.length; i+=1) {
                const key = mine.config.basic.isNeedLocationSearch[i];
                searchParams[key] = mine.searchParams[key];
            }
        }
        return parseData2Url({
                ...parseFixedParameter(mine.config.fixedParameter),
                ...parseFixedParameter(mine.config.basic.fixedParameter),
                ...searchParams,
                ...searchForm,
                ...mine.state.searchForm,
                ...(params || {})
            }, url, mine.config.basic.accept, mine.config.basic.urlParams);
    }

    fetchDataHandler = (params) => {
        const mine = this;
        const { data, url } = mine.getSearchData(mine.config.basic[`${this.env}url`], params);
		if (url) {
			xhr({
				url,
				method: mine.config.basic.method || 'get',
				data,
				type: 'json',
			    contentType: mine.config.basic.contentType,
                notSwitchArrToStr: mine.config.basic.notSwitchArrToStr
			}).then((rs) => {
				if (rs[projectConfig.codeKey] === projectConfig.code) {
                    let detailData = {};
                    if (mine.config.basic.list) detailData = rs.data[mine.config.basic.list] || {};
                    else detailData = rs.data || {};
                    mine.setState({
                        detailData
                    });
				} else {
					error(rs[projectConfig.msg]);
				}
			});
		}
    };

    exportDataHandler = () => {
        const mine = this;
        const { type, method='get' } = mine.config.export;
        const { data, url } = mine.getSearchData(mine.config.export[`${this.env}url`], {});
        if (type === 'attachment') {
            const searchFormArr = [];
            Object.keys(data).forEach((key) => {
                searchFormArr.push(`${key}=${data[key]}`);
            });
            if (method === 'get' || method === 'GET') {
                window.open(`${url}?${searchFormArr.join('&')}`)
            } else {
                $.ajax({
                    url,
                    method,
                    data,
                    type: 'json',
                    success: (response, status, request) => {
                        if (response.code === 400) {
                            error(response[projectConfig.msg]);
                        } else {
                            const disp = request.getResponseHeader('Content-Disposition');
                            if (disp && disp.search('attachment') !== -1) {
                                const formStr = searchFormArr.join('&');
                                const form = $(`<form method="POST" action="${url}?${formStr}">`);
                                form.append($('<input type="hidden" name="filename">'));
                                $('body').append(form);
                                form.submit();
                            }
                        }
                    }
                });
            }
        }
    }

    switchData = (item) => {
        const mine = this;
        const { detailData = {} } = mine.state;
        let result = '';
        if (item.switchtype === 'timestamp') {
            if (detailData[item.key]) result = moment(detailData[item.key]).format(item.format || 'YYYY-MM-DD HH:mm:ss');
        } else if (item.switchtype === 'second') {
            if (detailData[item.key]) result = moment(detailData[item.key] * THOUSAND).format(item.format || 'YYYY-MM-DD HH:mm:ss');
        } else if (item.switchtype === 'str2array') {
            if (detailData[item.key]) result = ((detailData[item.key] || '').split(item.separator || '\n') || []).map((aItem) => <div>{aItem}</div>);
        } else {
            result = detailData[item.key];
        }
        return result || '';
    }

    getDetailContent = () => {
        const mine = this;
        const { detailData = {} } = mine.state;
        return mine.config.basic.justjson ? Object.keys(detailData).map((item) => {
            return (<Row className='row'>
                        <Col size={mine.config.basic.labelSize || 6} className={`label ${mine.config.basic.border ? 'border-label' : ''}`}>
                            { item }{mine.config.basic.border ? '' : '：'}
                        </Col>
                        <Col size={mine.config.basic.valueSize || 18} className={`value ${mine.config.basic.border ? 'border-value' : ''}`}>
                            { detailData[item] }
                        </Col>
                    </Row>);
        }) : (mine.config.basic.columns || []).map((item) => {
            return (<Row className='row'>
                        <Col size={mine.config.basic.labelSize || 6} className={`label ${mine.config.basic.border ? 'border-label' : ''}`}>
                            { item.label }{mine.config.basic.border ? '' : '：'}
                        </Col>
                        <Col size={mine.config.basic.valueSize || 18} className={`value ${mine.config.basic.border ? 'border-value' : ''}`}>
                            { mine.switchData(item) }
                        </Col>
                    </Row>);
        });
    }

    switchJsOrJson = (data) => {
        xhr({
            url: '/local/api/switchJsOrJson',
            method: 'post',
            data,
            type: 'json'
        }).then((rs) => {
            if (rs[projectConfig.codeKey] === projectConfig.code) {
                success('格式转换成功!');
            } else {
                error(rs[projectConfig.msg]);
            }
        });
    }
    
    render() {
        const { detailData } = this.state;
        return (
            <Row className="mb-10 detail-list">
                <Col>
                    <div className={this.config.nbg ? '' : 'section'}>
                        {
                            !this.props.notModify && this.env === 'local.' ? <Button
                                variant="contained" color="info"
                                size="small"
                                style={{"height": "auto", "float": "right"}}
                                onClick={() => {
                                    this.switchJsOrJson({
                                        path: this.props.path,
                                        uuid: this.config.uuid
                                    })
                                }}>toJS</Button> : ''
                        }
                        <div className="tool-bar">
                            {
                                this.config.filter && this.config.filter.length > 0 ? <SearchBar
                                    filter={this.config.filter || []}
                                    search={this.fetchDataHandler}
                                    searchFormData={this.state.searchForm}
                                ></SearchBar> : ''
                            }
                        </div>
                        {
                            (this.config.name || this.config.export) ? <div className="table-action" style={{
                                height: '54px',
                                lineHeight: '54px',
                                padding: '0 5px'
                            }}>
                                {
                                    this.config.name ? <span style={{fontSize: 16, fontWeight: 'bold'}}>{ this.config.name }</span> : ''
                                }
                                {
                                    this.config.name && this.config.description ? <span style={{ marginLeft: 12 }}>({ this.config.description })</span> : ''
                                }
                                {
                                    this.config.export && Object.keys(detailData).length > 0 ? <Button
                                        variant="contained" color={this.config.export.primary || 'primary'}
                                        onClick={this.exportDataHandler}
                                        style={{ float: 'right', marginLeft: '10px', marginRight: '10px' }}
                                    >导出数据</Button> : ''
                                }
                            </div> : ''
                        }
                        { this.getDetailContent() }
                    </div>
                </Col>
            </Row>
        );
    }
}

export default withRouter(Detaillist);
