import React from 'react';
import PropTypes from 'prop-types';
import compose from 'ramda/src/compose';
import withHandlers from 'recompose/withHandlers';
import styled from 'styled-components';
import { ellipsis } from 'polished';

import { Places } from '@descarteslabs/descarteslabs';

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 {
    flex_col,
    flex_row,
    icon_base,
    text,
} from '@descarteslabs/pizzazz/styles/mixins';
import OpenPanelIcon from '@descarteslabs/pizzazz/styles/icons/chevron-single-down.svg';
import ClosePanelIcon from '@descarteslabs/pizzazz/styles/icons/chevron-single-up.svg';
import SearchIcon from '@descarteslabs/pizzazz/styles/icons/search.svg';
import LoadingSpinner from '@descarteslabs/pizzazz/styles/icons/loading-blue.svg';

// Main container.
const PanelContainer = styled.div`
    min-width: 300px;
    max-height: 100%;
`;
// Icon styling.
const iconContainerWidth = dimensions.medium;
const iconWidth = dimensions.x_small;
const topBarMargin = dimensions.base_small;
const IconNoClickContainer = styled.div`
    position: relative;
    height: inherit;
    width: ${iconContainerWidth};
    z-index: 1;
    padding: ${dimensions.base_small};

    & svg {
        ${icon_base({ size: iconWidth, width: iconWidth })};
    }
`;
const IconContainer = IconNoClickContainer.extend`
    &:hover {
        cursor: pointer;
    }
`;
const SearchIconContainer = styled.div`
    height: inherit;
    width: ${iconWidth};
    margin-left: 0.5rem;
    position: absolute;
    top: 0;
    left: ${topBarMargin};
    z-index: 1;
    & svg {
        ${icon_base({ size: iconWidth, width: iconWidth })};
    }
`;
const ToggleMenuIconContainer = IconContainer.extend`
    position: absolute;
    top: 0;
    right: 0;
`;
const TopBarContainer = styled.div`
    height: 3.75rem;
    position: relative;
    border-bottom: 1px solid ${colors.stroke[1]};
    z-index: 3;
`;
const MenuContainer = styled.div`
    display: ${({ showMenu }) => (showMenu ? 'initial' : 'none')};
`;

const imageContainerWidth = '4rem';

/* Search result section */

const SearchResultContainer = styled.div`
    ${flex_row({ justify: 'flex-start' })}
    border-bottom: 1px solid ${colors.stroke[0]};
    height: 3rem;
    width: 100%;

    &:hover {
        background-color: ${colors.fill[3]};
    }
`;

const SearchResultImageContainer = styled.span`
    ${flex_row()}
    flex: 0 0 ${imageContainerWidth};
    margin-left: ${dimensions.small};
    margin-top: ${dimensions.base_small};
`;
const SearchResultImage = styled.img`
    height: 2rem;
    width: 2rem;
`;

const SearchResultTextContainer = styled.span`
    ${flex_col({ justify: 'space-around', align: 'flex-start' })}
    width: calc(100% - ${imageContainerWidth} - .5rem);
    min-width: calc(100% - ${imageContainerWidth} - .5rem);
`;
const SearchResultName = styled.span`
    ${text({ weight: 'semibold' })}
`;
const SearchResultMetadata = styled.span`
    ${text({ size: 'small', weight: 'light' })}
    ${ellipsis('100%')}
`;

const resultEnhancer = compose(
    withHandlers({
        onSelectResult: ({ result, onSelectResult }) => _ => onSelectResult(result),
    }),
);

const SearchResult = resultEnhancer(({ result, onSelectResult }) => (
    <SearchResultContainer onMouseDown={onSelectResult}>
        <SearchResultImageContainer>
            <SearchResultImage
                alt="N/A"
                src={Places.thumbnail_url(result.bbox, result.id)}
            />
        </SearchResultImageContainer>
        <SearchResultTextContainer>
            <SearchResultName>
                {result.name}
            </SearchResultName>
            <SearchResultMetadata>
                {result.metadata}
            </SearchResultMetadata>
        </SearchResultTextContainer>
    </SearchResultContainer>
));

/* Search results section */

const SearchResultsContainer = styled.div`
    ${shadows.medium};
    background-color: white;
    border-top: 1px solid ${colors.stroke[0]};
    cursor: default;
    position: relative;
    z-index: -1;

    & div:last-child {
        border-bottom: none;
    }
`;

const ResultsComponent = ({ results, onSelectResult }) => (
    <SearchResultsContainer>
        {results.map(result =>
            <SearchResult
                key={result.id}
                result={result}
                onSelectResult={onSelectResult}
            />
        )}
    </SearchResultsContainer>
);

ResultsComponent.propTypes = {
    results: PropTypes.array,
    onSelectResult: PropTypes.func,
};

ResultsComponent.defaultProps = {
    results: [],
    onSelectResult: () => {},
};

const TextSearchVtreeContainer = styled.div`
    background-color: ${colors.fill[0]};
    border-bottom: 1px solid ${colors.stroke[2]};
    box-sizing: content-box;
    height: inherit;
    width: inherit;
    position: relative;
    & input {
        margin-left: calc(${iconWidth} + ${topBarMargin});
        width: calc(100% - ${iconWidth} - 2 * ${topBarMargin});
        &::placeholder {
            line-height: -moz-block-height;
        }
    }
`;
const StyledLoadingIcon = styled.div`
    height: inherit;
    position: absolute;
    top: 0;
    right: ${iconContainerWidth};
    z-index: 1;
`;
const LoadingIcon = styled(LoadingSpinner)`
    ${icon_base({ size: '1.25rem', width: iconWidth })}
    @keyframes spin {
        from { transform: rotate(0deg); }
        to { transform: rotate(360deg); }
    }
    animation: spin 1s linear infinite;
`;

/* View */

const PanelView = ({
    isLoading, showMenu, menuVtree, textSearchVtree, onOpenMenu, onCloseMenu,
}) => (
    <PanelContainer
        showMenu={showMenu}
    >
        <TopBarContainer>
            <SearchIconContainer>
                <SearchIcon />
            </SearchIconContainer>
            <TextSearchVtreeContainer>
                {textSearchVtree}
            </TextSearchVtreeContainer>
            <StyledLoadingIcon>
                {isLoading ? <LoadingIcon /> : null}
            </StyledLoadingIcon>
            <ToggleMenuIconContainer
                onClick={showMenu ? onCloseMenu : onOpenMenu}
            >
                {showMenu ? <ClosePanelIcon /> : <OpenPanelIcon />}
            </ToggleMenuIconContainer>
        </TopBarContainer>
        <MenuContainer
            showMenu={showMenu}
        >
            {menuVtree}
        </MenuContainer>
    </PanelContainer>
);

PanelView.propTypes = {
    isLoading: PropTypes.bool.isRequired,
    menuVtree: PropTypes.element.isRequired,
    showMenu: PropTypes.bool.isRequired,
    textSearchVtree: PropTypes.element.isRequired,
    onCloseMenu: PropTypes.func.isRequired,
    onOpenMenu: PropTypes.func.isRequired,
};

export { ResultsComponent };

export default (
    textSearchVtree, menuVtree,
    {
        isLoading, showMenu, onOpenMenu, onCloseMenu,
    }
) => PanelView({
    textSearchVtree,
    menuVtree,
    isLoading,
    showMenu,
    onOpenMenu,
    onCloseMenu,
});
