import React, { forwardRef, useEffect, useState } from 'react';
import isNumber from 'reneco-utils/isNumber';
import Link from './Link';

export default forwardRef(({
    blocks: $blocks,
    getEndPoint,
    getBlock
}, ref) => {
    const [{selected, links, lastMove}, setState] = useState({selected: null, links: [], lastMove: null}),
        calculateLinks = (ix1, anchors, links, getStyle) => {
            if(anchors) {
                const changedLinks = anchors.reduce((changed, startPoint) => {
                    const ix2 = startPoint.id,
                        prevLink = isNumber(ix2)
                            ? links.find(link =>
                                link.id === startPoint.id
                                && link.rix === startPoint.rix
                            )
                            : null,
                        targetPoint = getEndPoint(ix2, startPoint.x, startPoint.y),
                        link = targetPoint && {
                            id: startPoint.id,
                            rix: startPoint.rix,
                            ix1,
                            ix2,
                            x1: startPoint.x,
                            y1: startPoint.y,
                            x2: targetPoint.x,
                            y2: targetPoint.y,
                            position: targetPoint.position,
                            color: getStyle && getStyle('link.color'),
                            width: getStyle && getStyle('link.width'),
                        };
                        if(link && (
                            !prevLink
                            || prevLink.x1 !== link.x1
                            || prevLink.y1 !== link.y1
                            || prevLink.x2 !== link.x2
                            || prevLink.y2 !== link.y2
                        )) {
                            changed.push(link);
                        }
                    return changed;
                }, [])
                return changedLinks;
            }
            return false;
        },
        select = ix => {
            setState(({links, ...pState}) => {
                const nLinks = links.slice();
                if((ix !== undefined && ix !== null)) {
                    nLinks.splice(ix, 1);
                    nLinks.push(links[ix]);
                }
                return ({
                    ...pState,
                    selected: (ix !== undefined && ix !== null) ? nLinks.length-1 : null,
                    links: nLinks
                });
            });
            onClick && onClick(links[ix]);
        },
        remove = ix => {
            setState(({links, ...pState}) => {
                const nLinks = links.slice();
                nLinks.splice(ix, 1);
                return ({
                    ...pState,
                    selected: null,
                    links: nLinks
                });
            });
            onDelete && onDelete(links[ix]);
        },
        onBlockMove = (id, position) => setState(pState => ({...pState, lastMove: `${id}:${position?.x},${position?.y}`}));
    useEffect(() => {
        // console.log('LINKS UPDATED');

        setState((pState => {

            return {
                ...pState,
                links: React.Children.toArray($blocks).reduce((links, b) => {
                    const block = getBlock(b.props.id),
                        anchors = block?.getLinkAnchors();
                    // console.log(calculateLinks(b.props.id, anchors, links, s => block.getStyle(s)));
                    return [...links, ...calculateLinks(b.props.id, anchors, links, s => block.getStyle(s))];
                }, [])
            }
        }))
    }, [lastMove, React.Children.map($blocks, ({key, props}) => `k${key}[${props.position?.join(':')}]:${props.relations?.join('-')}>${React.Children.map(props.children, row => row?.props?.relations?.join('-'))?.join('|')}`).join(';')]);

    // console.log(links);
    useEffect(() => {
        if(ref) {
            ref.current = {
                onBlockMove
            };
            return () => {
                ref.current = null;
            };
        }
    }, []);

    return (<>
        {links && links.length>0 &&  links.map(({
            width,
            ix1,
            ix2,
            rix,
            x1,
            y1,
            x2,
            y2,
            position,
            color
        }, ix) => (<Link
            // selected={selected === ix}
            width={width}
            key={`${ix1}-${ix2}-${rix}`}
            x1={x1}
            y1={y1}
            x2={x2}
            y2={y2}
            targetPosition={position}
            color={color}
            onClick={e => select(ix)}
            onClickDelete={e => remove(ix)}
        />))}
    </>);
})