import { Popover, Button ,Checkbox,Empty } from 'antd';
import * as React from 'react';
import * as Tool from 'jad-tool'



const Tools = Tool.extend({
	setCacheData(key:string,value:any){
		window.localStorage.setItem('JG_FilterColumns_cacheFlag'+key,JSON.stringify(value))
	},
	getCacheData(key:string){
		var value = window.localStorage.getItem('JG_FilterColumns_cacheFlag'+key)
		return value?JSON.parse(value):false
	}
},Tool)


type ColumnItem = { 
	title:  string|Function,				//标题
	dataIndex: string,						//index
	checked?: boolean,						//是否选择
	required?: boolean,						//必选
	group?: string,							//分类组名
} 



//react component
export class FilterColumns extends React.Component<{
	title?: string | React.ReactNode;
	style?:any;
	children: React.ReactNode;
	columns: ColumnItem[];
	receivePropsUpdate?:boolean				//接收props是否更新
	onChangeKey?: any;						//返回自定义后的dataIndex[]
	onChangeColums?: any;					//返回自定义后的columns[]
	initCallback?: boolean;					//初始化后是否需要回调一次,恢复缓存考虑
	cacheKey?: string;
}> {
	state = {
		visible:false,
		renderGroupBuff:{},
		groupLength:0,
		init:false,
	}


	componentDidMount(){
		const { columns,cacheKey } = this.props;
		let columnsBuff = cacheKey?  (Tools.getCacheData(cacheKey)?Tools.getCacheData(cacheKey):columns)  :columns
		this.init(columnsBuff)
	}

	UNSAFE_componentWillReceiveProps(nextProps){
		if(!this.state.init) return ;
		const { receivePropsUpdate } = this.props
		const oldGroupLength = this.state.groupLength
		const newGroupLength = nextProps.columns.length
		if(oldGroupLength === 0 && receivePropsUpdate){
			console.warn('[jad-lib-react]:FilterColumns->receivePropsUpdate在更新columns的时候,检测到origin columns为空,请确保初始columns在初始化的时候被赋值')
		}
		if(oldGroupLength !== newGroupLength && receivePropsUpdate){
			this.init(nextProps.columns)
		}
	}

	private init(columnsBuff:any[]){
		const { initCallback } = this.props;
		let renderGroupBuff = {}
		const groupLength = columnsBuff.length
		columnsBuff.map( e =>{
			let item = Object.assign({},e)	//防止引用类型穿透
			var groupName = item.required? 'required': (item.group || '其他')
			let group = renderGroupBuff[groupName] || []
			item.checked = item.required? true: (item.checked?true:false)
			item.group = groupName
			group.push(item)
			renderGroupBuff[groupName] = group
			return item
		})
		this.setState({
			renderGroupBuff,
			groupLength,
			init:true
		},()=>{
			if(initCallback){
				this.onHandleOk()
			}
		})
	}

	private onHandleChecked(checkData,target){
		let { renderGroupBuff } = this.state
		let checked = target.target.checked
		// all Check
		if(Tools.isArray(checkData)){
			var groupName = checkData[0].group
			renderGroupBuff[groupName] = renderGroupBuff[groupName].map(item => {item.checked = checked; return item})
		}else{
			var groupName = checkData.group
			var dataIndex = checkData.dataIndex
			renderGroupBuff[groupName] = renderGroupBuff[groupName].map(item => {
				if(item.dataIndex === dataIndex){
					item.checked = checked; 
				}
				return item
			})
		}
		this.setState({
			renderGroupBuff
		})
		
		this.onHandleOk()
	}


	private onHandleOk(){
		const { onChangeKey, onChangeColums,cacheKey,columns } = this.props;
		const { renderGroupBuff } = this.state
		var filterBuff = []
		for(let key in renderGroupBuff){
			renderGroupBuff[key].map(item=>{filterBuff[item.dataIndex]=item ;return item})
		}
		let newColumsCache = columns.map((e) =>{
			let item = Object.assign({},e)//防止引用类型穿透
			item.checked = filterBuff[item.dataIndex]?filterBuff[item.dataIndex].checked:item.checked
			return item
		})
		//return [dataIndex(string),...]
		if(onChangeKey && Tools.isFunction(onChangeKey)){
			var resultKey = newColumsCache.filter(item => {
				if(item.checked){
					return item
				}
			}).map(e => e.dataIndex)
			onChangeKey(resultKey)
		}
		//return [groupItem(object),....]
		if(onChangeColums && Tools.isFunction(onChangeColums)){
			onChangeColums(newColumsCache)
		}
		//update cache
		if(!Tool.isEmptyArray(newColumsCache)){
			Tools.setCacheData(cacheKey,newColumsCache)
		}
		return false;
	}


	private onHandleVisibleChange(visible){
		this.setState({
			visible
		})
	}


	private renderRequiredGroup(groupData){
		if(!groupData || Tool.isEmptyArray(groupData)){
			return null
		}
		return (
			<div className='jad-filtercolums-group-container' key="required">
				<p className='label'>
					<label>必选项</label>
				</p>
				<div className='content'>
					{
						groupData.map( (item,index) =>{
							return (
								<Checkbox key={item.dataIndex} defaultChecked disabled>
									{Tools.isFunction(item.title)?item.title():item.title}
								</Checkbox>
							)
						})
					}
				</div>
			</div>
		)
	}


	private renderGroup(groupName,groupData){
		let checkedAll = false;
        checkedAll = groupData.every((obj)=>{
                if(obj.checked)
                return true
        })
		return (
			<div className='jad-filtercolums-group-container' key={groupName}>
				<p className='label'>
					<label>{groupName}</label>
					<span className='checkBox'>
						<Checkbox checked={checkedAll} onChange={event => this.onHandleChecked(groupData,event)}>全选</Checkbox>
					</span>
				</p>
				<div className='content'>
					{
						groupData.map( (item,index) =>{
							return (
								<Checkbox
									key={item.dataIndex}
									checked={item.checked}
									onChange={event => this.onHandleChecked(item,event)} 
								>
									{Tools.isFunction(item.title)?item.title():item.title}
								</Checkbox>
							)
						})
					}
				</div>
			</div>
		)
	}


	private renderContent(){
		const { renderGroupBuff } = this.state
		if(Tool.isEmptyObject(renderGroupBuff)){
			return <Empty/>
		}
		//这里之前存在问题keys是无序列的
		const requiredGroup = Tool.filter(renderGroupBuff,(e,key)=>key === 'required')
		const otherGroup = Tool.filter(renderGroupBuff,(e,key)=>key !== 'required')
		return (
			<React.Fragment>
				<div className='jad-filtercolums-group-wrap'>
					{this.renderRequiredGroup(requiredGroup['required'])}
					{Object.keys(otherGroup).map(key =>{
						var group = otherGroup[key]
						return this.renderGroup(key,group)
					})}
				</div>
			</React.Fragment>
		)
	}


	private renderTitle(){
		const { 
			title,
		} = this.props
		return (
			<p className='jad-filtercolums-title-container'>
				{title?title:'自定义列'}
			</p>
		)
	}


	//render filter component groud
  	public render() {
		const { children,style } = this.props
		const { visible } = this.state
		//render
		return (
			<Popover 
				placement={'bottomRight'}
				// trigger={'click'}
				trigger={'hover'}
				overlayClassName='jad-filtercolums-container'
				title={this.renderTitle()} 
				content={this.renderContent()}
				visible={visible}
				overlayStyle={style}
				onVisibleChange={this.onHandleVisibleChange.bind(this)}
			>
				{children}
			</Popover>
		)
  	}
}
