/* global document */

import React from 'react';
import PropTypes from 'prop-types';
import withHandlers from 'recompose/withHandlers';
import styled from 'styled-components';
import { tint } from 'polished';

import * as colors from '@descarteslabs/pizzazz/styles/colors';
import * as shadows from '@descarteslabs/pizzazz/styles/shadows';
import * as dimensions from '@descarteslabs/pizzazz/styles/dimensions';
import * as fonts from '@descarteslabs/pizzazz/styles/fonts';
import { flex_row, flex_col, icon_base } from '@descarteslabs/pizzazz/styles/mixins';
import LoadingSpinner from '@descarteslabs/pizzazz/styles/icons/loading-blue.svg';
import CloseIcon from '@descarteslabs/pizzazz/styles/icons/close-medium-f01.svg';
import CopyStaticXYZURLIcon from '@descarteslabs/pizzazz/styles/icons/clipboard-add.svg';

import Button from '@descarteslabs/cycle-widgets/es2015/Button';
import { accessClass } from '@descarteslabs/cycle-widgets/es2015/utils/access';

const BUTTON_BORDER_COLOR = colors.primary.blue;
const BUTTON_COLOR = colors.fill[2];

/* Styled components */

// Icon stylings
const iconWidth = '1.5rem';
const IconNoClickContainer = styled.div`
    position: relative;
    height: inherit;
    z-index: 1;
    & svg {
        ${icon_base({ size: iconWidth, width: iconWidth })};
    }
`;
const IconContainer = IconNoClickContainer.extend`
    &:hover {
        cursor: pointer;
    }
`;

// Button and icon containers
const ButtonContainer = styled.div`
    position: relative;
    text-align: center;
    width: 50%;
    padding: ${dimensions.base_small};
    align-self: center;
    & button {
        width: 100%;
        border: 1px solid ${BUTTON_BORDER_COLOR};
        color: ${BUTTON_COLOR};
        &:hover {
            border-color: ${tint(0.8, BUTTON_BORDER_COLOR)};
            color: ${tint(0.8, BUTTON_COLOR)};
        }
        &:focus {
            box-shadow: none;
        }
    }
`;

const StyledLoadingIcon = styled.div`
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -1rem;
    margin-left: -1rem;
    z-index: 1;
`;
const loadingIconWidth = '2rem';
const LoadingIcon = styled(LoadingSpinner)`
    ${icon_base({ size: '1.25rem', width: loadingIconWidth })}
    @keyframes spin {
        from { transform: rotate(0deg); }
        to { transform: rotate(360deg); }
    }
    animation: spin 1s linear infinite;
`;

/* Static XYZ Layer */

const StaticXYZLayerContainer = styled.div`
    ${flex_col()}
    padding: ${dimensions.base_small};
`;
const StaticXYZLayerLabelContainer = styled.div`
    margin-bottom: ${dimensions.base_small};
`;
const StaticXYZLayerPanelContainer = styled.div`
    ${flex_row({ align: 'center', justify: 'space-around' })}
    font-weight: 300;
    padding: ${dimensions.base_small};
    background: ${colors.fill[1]};
    ${({ color }) => (color
        ? `border-left: ${dimensions.base_small} solid ${color};`
        : ''
    )}
`;
const URLContainer = styled.div`
    word-wrap: break-word;
    margin: 0 ${dimensions.base_small};
    max-width: 90%;
`;
const StaticXYZLayerButtonsContainer = styled.div`
    ${flex_row({ wrap: 'nowrap', justify: 'space-around' })}
    margin-top: ${dimensions.base_small};
    margin-right: 0.1875rem;
`;
const BaseStaticXYZContainer = styled.div`
    position: relative;
    padding: 0;
    margin-left: calc(${dimensions.base_small}/2);
    margin-right: calc(${dimensions.base_small}/2);
`;
const CopyStaticXYZContainer = BaseStaticXYZContainer.extend``;
const StaticXYZLayer = ({ label, layerUrl, color, onCopy }) => (
    <StaticXYZLayerContainer>
        <StaticXYZLayerLabelContainer>
            {label}
        </StaticXYZLayerLabelContainer>
        <StaticXYZLayerPanelContainer
            color={color}
        >
            <URLContainer>
                {layerUrl}
            </URLContainer>
            <StaticXYZLayerButtonsContainer>
                <CopyStaticXYZContainer
                    onClick={onCopy}
                >
                    <IconContainer>
                        <CopyStaticXYZURLIcon />
                    </IconContainer>
                </CopyStaticXYZContainer>
            </StaticXYZLayerButtonsContainer>
        </StaticXYZLayerPanelContainer>
    </StaticXYZLayerContainer>
);

const staticLayerEnhancer = withHandlers({
    onCopy: ({ layerType, onCopyXYZLayer }) => _ => onCopyXYZLayer(layerType),
});

const EnhancedStaticXYZLayer = staticLayerEnhancer(StaticXYZLayer);

StaticXYZLayer.propTypes = {
    label: PropTypes.string.isRequired,
    layerUrl: PropTypes.string.isRequired,
    onCopy: PropTypes.func.isRequired,
    color: PropTypes.string,
};

/* Static Layers */

// Main container.
const StaticXYZContainer = styled.div`
    position: absolute;
    left: 50%;
    top: 5%;
    max-height: 90%;
    width: 700px;
    margin-left: -350px;
    background: ${colors.fill[2]};
    display: ${({ expanded }) => (expanded ? 'flex' : 'none')};
    overflow: hidden;
    ${shadows.medium}
    border-radius: 2px;
    z-index: 5;
`;
const StaticXYZLabelContainer = styled.div`
    ${flex_row({ align: 'center' })}
    padding: ${dimensions.base_small};
    background: ${colors.primary.blue};
    color: ${colors.fill[2]};
`;
const StaticXYZLabel = styled.div`
    font-size: ${fonts.sizes.medium};
    width: 100%;
    text-align: center;
`;
const StaticXYZLayersWrapper = styled.div`
    position: relative;
    margin: ${dimensions.base_small};
    margin-left: 1.925rem;
    overflow: auto;
    min-height: ${({ loading }) => (loading ? `calc(${loadingIconWidth} + ${dimensions.base})` : 'initial')};
    max-width: 95%;
`;
const StaticXYZLayersContainer = styled.div`
    opacity: ${({ loading }) => (loading ? '0.7' : '1')};
`;
const StaticXYZClose = styled.div`
    position: absolute;
    top: ${dimensions.base_small};
    right: ${dimensions.base_small};

    &:hover {
        cursor: pointer;
    }
`;
const StaticXYZWrapper = styled.div`
    position: relative;
    ${flex_col()}
    width: 100%;
`;

const DeleteXYZLayerButtonContainer = ButtonContainer.extend`
    margin: ${dimensions.base};
`;

export default class StaticXYZPanel extends React.Component { // eslint-disable-line react/no-multi-comp

    static propTypes = {
        expanded: PropTypes.bool.isRequired,
        loading: PropTypes.bool.isRequired,
        staticLayer: PropTypes.object.isRequired,
        onCloseXYZPanel: PropTypes.func.isRequired,
        onCopyXYZLayer: PropTypes.func.isRequired,
        onDeleteXYZLayer: PropTypes.func.isRequired,
    };

    componentDidMount() {
        document.addEventListener('mousedown', this.handleClickOutside);
    }

    componentWillUnmount() {
        document.removeEventListener('mousedown', this.handleClickOutside);
    }

    setWrapperRef = node => {
        this.wrapperRef = node;
    }

    handleClickOutside = event => {
        if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
            this.props.onCloseXYZPanel();
        }
    }

    render() {
        const { loading, staticLayer, expanded, onCopyXYZLayer, onDeleteXYZLayer, onCloseXYZPanel } = this.props;
        return (
            <StaticXYZContainer
                className={accessClass('static_xyz')}
                expanded={expanded}
                innerRef={this.setWrapperRef}
            >
                <StaticXYZWrapper>
                    <StaticXYZLabelContainer>
                        <StaticXYZLabel>
                            Static URLs
                        </StaticXYZLabel>
                    </StaticXYZLabelContainer>
                    <StaticXYZLayersWrapper
                        loading={loading}
                    >
                        {Object.keys(staticLayer).length > 0
                            ? <StaticXYZLayersContainer
                                loading={loading}
                            >
                                <EnhancedStaticXYZLayer
                                    key="tms"
                                    label="TMS URL"
                                    layerType="tms"
                                    layerId={staticLayer.id}
                                    layerUrl={staticLayer.tms}
                                    color={staticLayer.color}
                                    onCopyXYZLayer={onCopyXYZLayer}
                                />
                                <EnhancedStaticXYZLayer
                                    key="arcGIS"
                                    label="ArcGIS Tile Layer URL"
                                    layerType="arcGIS"
                                    layerId={staticLayer.id}
                                    layerUrl={staticLayer.arcGIS}
                                    color={staticLayer.color}
                                    onCopyXYZLayer={onCopyXYZLayer}
                                />
                                <EnhancedStaticXYZLayer
                                    key="tableau"
                                    label="Tableau TMS XML"
                                    layerType="tableau"
                                    layerId={staticLayer.id}
                                    layerUrl={staticLayer.tableau}
                                    color={staticLayer.color}
                                    onCopyXYZLayer={onCopyXYZLayer}
                                />
                            </StaticXYZLayersContainer>
                            : null
                        }
                        {loading
                            ? <StyledLoadingIcon>
                                <LoadingIcon />
                            </StyledLoadingIcon>
                            : null
                        }
                    </StaticXYZLayersWrapper>
                    <DeleteXYZLayerButtonContainer>
                        <Button
                            name="delete-static-xyz"
                            displayStyle="primary"
                            size="medium"
                            onClick={onDeleteXYZLayer}
                        >
                            Delete Static URL Layer
                        </Button>
                    </DeleteXYZLayerButtonContainer>
                    <StaticXYZClose
                        onClick={onCloseXYZPanel}
                    >
                        <IconContainer>
                            <CloseIcon />
                        </IconContainer>
                    </StaticXYZClose>
                </StaticXYZWrapper>
            </StaticXYZContainer>
        );
    }
}
