import React, { Fragment, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { Trans } from 'react-i18next';
import Modal from 'react-modal';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import queryString from 'query-string';
import classNames from 'classnames';
import {
    BLOCK_ACTIONS,
    TABLE_DEFAULT_PAGE_SIZE,
    TABLE_FIRST_PAGE,
    smallScreenSize,
} from '../../helpers/constants';
import Loading from '../ui/Loading';
import Filters from './Filters';
import Table from './Table';
import Disabled from './Disabled';
import { getFilteringStatus } from '../../actions/filtering';
import { getClients } from '../../actions';
import { getDnsConfig } from '../../actions/dnsConfig';
import {
    getLogsConfig,
    refreshFilteredLogs,
    resetFilteredLogs,
    setFilteredLogs,
} from '../../actions/queryLogs';
import { addSuccessToast } from '../../actions/toasts';
import './Logs.css';

const processContent = (data, buttonType) => Object.entries(data)
    .map(([key, value]) => {
        if (!value) {
            return null;
        }

        const isTitle = value === 'title';
        const isButton = key === buttonType;
        const isBoolean = typeof value === 'boolean';
        const isHidden = isBoolean && value === false;

        let keyClass = 'key-colon';

        if (isTitle) {
            keyClass = 'title--border';
        }
        if (isButton || isBoolean) {
            keyClass = '';
        }

        return isHidden ? null : <Fragment key={key}>
            <div
                className={classNames(`key__${key}`, keyClass, {
                    'font-weight-bold': isBoolean && value === true,
                })}>
                <Trans>{isButton ? value : key}</Trans>
            </div>
            <div className={`value__${key} text-pre text-truncate`}>
                <Trans>{(isTitle || isButton || isBoolean) ? '' : value || '—'}</Trans>
            </div>
        </Fragment>;
    });


const Logs = (props) => {
    const dispatch = useDispatch();
    const history = useHistory();

    const {
        response_status: response_status_url_param = '',
        search: search_url_param = '',
    } = queryString.parse(history.location.search);

    const { filter } = useSelector((state) => state.queryLogs, shallowEqual);

    const search = filter?.search || search_url_param;
    const response_status = filter?.response_status || response_status_url_param;

    const [isSmallScreen, setIsSmallScreen] = useState(window.innerWidth < smallScreenSize);
    const [detailedDataCurrent, setDetailedDataCurrent] = useState({});
    const [buttonType, setButtonType] = useState(BLOCK_ACTIONS.BLOCK);
    const [isModalOpened, setModalOpened] = useState(false);
    const [isLoading, setIsLoading] = useState(false);


    useEffect(() => {
        (async () => {
            setIsLoading(true);
            await dispatch(setFilteredLogs({
                search,
                response_status,
            }));
            setIsLoading(false);
        })();
    }, [response_status, search]);

    const {
        filtering,
        setLogsPage,
        setLogsPagination,
        toggleDetailedLogs,
        dashboard,
        dnsConfig,
        queryLogs: {
            enabled,
            processingGetConfig,
            processingAdditionalLogs,
            processingGetLogs,
            oldest,
            logs,
            pages,
            page,
            isDetailed,
        },
    } = props;

    const mediaQuery = window.matchMedia(`(max-width: ${smallScreenSize}px)`);
    const mediaQueryHandler = (e) => {
        setIsSmallScreen(e.matches);
        if (e.matches) {
            toggleDetailedLogs(false);
        }
    };

    const closeModal = () => setModalOpened(false);

    const getLogs = (older_than, page, initial) => {
        if (enabled) {
            props.getLogs({
                older_than,
                page,
                pageSize: TABLE_DEFAULT_PAGE_SIZE,
                initial,
            });
        }
    };

    useEffect(() => {
        try {
            mediaQuery.addEventListener('change', mediaQueryHandler);
        } catch (e1) {
            try {
                // Safari 13.1 do not support mediaQuery.addEventListener('change', handler)
                mediaQuery.addListener(mediaQueryHandler);
            } catch (e2) {
                console.error(e2);
            }
        }

        (async () => {
            setIsLoading(true);
            dispatch(setLogsPage(TABLE_FIRST_PAGE));
            dispatch(getFilteringStatus());
            dispatch(getClients());
            try {
                await Promise.all([
                    dispatch(getLogsConfig()),
                    dispatch(getDnsConfig()),
                ]);
            } catch (err) {
                console.error(err);
            } finally {
                setIsLoading(false);
            }
        })();

        return () => {
            try {
                mediaQuery.removeEventListener('change', mediaQueryHandler);
            } catch (e1) {
                try {
                    mediaQuery.removeListener(mediaQueryHandler);
                } catch (e2) {
                    console.error(e2);
                }
            }

            dispatch(resetFilteredLogs());
        };
    }, []);

    const refreshLogs = async () => {
        setIsLoading(true);
        await Promise.all([
            dispatch(setLogsPage(TABLE_FIRST_PAGE)),
            dispatch(refreshFilteredLogs()),
        ]);
        dispatch(addSuccessToast('query_log_updated'));
        setIsLoading(false);
    };

    return (
        <>
            {enabled && processingGetConfig && <Loading />}
            {enabled && !processingGetConfig && (
                <>
                    <Filters
                        filter={{
                            response_status,
                            search,
                        }}
                        setIsLoading={setIsLoading}
                        processingGetLogs={processingGetLogs}
                        processingAdditionalLogs={processingAdditionalLogs}
                        refreshLogs={refreshLogs}
                    />
                    <Table
                        isLoading={isLoading}
                        setIsLoading={setIsLoading}
                        logs={logs}
                        pages={pages}
                        page={page}
                        autoClients={dashboard.autoClients}
                        oldest={oldest}
                        filtering={filtering}
                        processingGetLogs={processingGetLogs}
                        processingGetConfig={processingGetConfig}
                        isDetailed={isDetailed}
                        setLogsPagination={setLogsPagination}
                        setLogsPage={setLogsPage}
                        toggleDetailedLogs={toggleDetailedLogs}
                        getLogs={getLogs}
                        setRules={props.setRules}
                        addSuccessToast={props.addSuccessToast}
                        getFilteringStatus={props.getFilteringStatus}
                        dnssec_enabled={dnsConfig.dnssec_enabled}
                        setDetailedDataCurrent={setDetailedDataCurrent}
                        setButtonType={setButtonType}
                        setModalOpened={setModalOpened}
                        isSmallScreen={isSmallScreen}
                    />
                    <Modal portalClassName='grid' isOpen={isSmallScreen && isModalOpened}
                           onRequestClose={closeModal}
                           style={{
                               content: {
                                   width: '100%',
                                   height: 'fit-content',
                                   left: 0,
                                   top: 47,
                                   padding: '1rem 1.5rem 1rem',
                               },
                               overlay: {
                                   backgroundColor: 'rgba(0,0,0,0.5)',
                               },
                           }}
                    >
                        <svg
                            className="icon icon--small icon-cross d-block d-md-none cursor--pointer"
                            onClick={closeModal}>
                            <use xlinkHref="#cross" />
                        </svg>
                        {processContent(detailedDataCurrent, buttonType)}
                    </Modal>
                </>
            )}
            {!enabled && !processingGetConfig && (
                <Disabled />
            )}
        </>
    );
};

Logs.propTypes = {
    getLogs: PropTypes.func.isRequired,
    queryLogs: PropTypes.object.isRequired,
    dashboard: PropTypes.object.isRequired,
    getFilteringStatus: PropTypes.func.isRequired,
    filtering: PropTypes.object.isRequired,
    setRules: PropTypes.func.isRequired,
    addSuccessToast: PropTypes.func.isRequired,
    setLogsPagination: PropTypes.func.isRequired,
    setLogsPage: PropTypes.func.isRequired,
    toggleDetailedLogs: PropTypes.func.isRequired,
    dnsConfig: PropTypes.object.isRequired,
};

export default Logs;