import React, { useState } from 'react';
import { useQuery, useMutation } from '@apollo/client';
import { isEmpty } from 'lodash';
import { useTranslation } from 'utils/i18n';

import { getOpportunityColor } from 'utils/helpers';

import { IOpportunity, IUserData, OpportunityExpectedOutcome } from 'typings';

import { OPPORTUNITIES } from 'graphql/queries/opportunities';
import {
  UPDATE_OPPORTUNITY,
  INVALIDATE_OPPORTUNITY,
  DISPLAY_OPPORTUNITY,
} from 'graphql/mutations/opportunities';

import SVGPhone from 'assets/svg/phone.svg';
import SVGFiber from 'assets/svg/wifihouse.svg';
import SVGInternet from 'assets/svg/FourGnet.svg';
import SVGAlltsaman from 'assets/svg/allt-saman.svg';
import SVGWatch from 'assets/svg/watch.svg';

import { EmptyMessage, ErrorMessage } from '@nova-hf/ui';

import Loader from '../components/loader/Loader';

import Opportunity from '../components/opportunity/Opportunity';
import OpportunityButton from '../components/opportunityButton/OpportunityButton';

interface IOpportunitiesListProps {
  authentication: any;
}

const OpportunitiesList = ({ authentication: { accountInput } }: IOpportunitiesListProps) => {
  const { t } = useTranslation(['opportunities', 'common']);

  const getIcon = (category: string) => {
    switch (mapCategory(category)) {
      case 'watch':
        return <SVGWatch />;
      case 'fiber':
        return <SVGFiber />;
      case 'internet':
        return <SVGInternet />;
      case 'service_bundle':
        return <SVGAlltsaman />;
      default:
        return <SVGPhone />;
    }
  };

  const mapCategory = (category: string) => {
    switch (category) {
      case 'Ljósleiðari':
        return 'fiber';
      case 'internet':
        return 'internet';
      case 'AlltSaman':
        return 'service_bundle';
      case 'Úrlausn':
        return 'watch';
      default:
        return 'mobile';
    }
  };

  const [updateOpportunity] = useMutation(UPDATE_OPPORTUNITY);
  const [invalidateOpportunity] = useMutation(INVALIDATE_OPPORTUNITY);
  const [displayOpportunity] = useMutation(DISPLAY_OPPORTUNITY);
  const [selectedId, setSelectedId] = useState('');
  const [message, setMessage] = useState('');

  // Tab controler
  const onOpportunityClick = (id: string) => {
    setSelectedId(id);
  };

  const onViewOpportunity = async (id: string) => {
    try {
      const res = await updateOpportunity({
        variables: {
          input: {
            id,
            status: 'Viewed',
          },
        },
      });

      if (res.data.updateOpportunity.error) {
        setMessage(res.data.updateOpportunity.error.message as string);
      }
    } catch (e) {
      setMessage(`${t('errors.general')}: ${e.message}`);
    }
  };

  const onExpectedOutcomeClick = async (
    id: string,
    expectedOutcome: OpportunityExpectedOutcome,
  ) => {
    try {
      const res = await updateOpportunity({
        variables: {
          input: {
            id,
            expectedOutcome: OpportunityExpectedOutcome[expectedOutcome].valueOf(),
          },
        },
        refetchQueries: ['opportunities'],
      });

      if (res.data.updateOpportunity.error) {
        setMessage(res?.data?.updateOpportunity?.error?.message as string);
      }
    } catch (e) {
      setMessage(`${t('errors.general')}: ${e.message}`);
    }
    onOpportunityClick('');
  };

  const onInvalidatedClick = async (id: string, note: string) => {
    try {
      const res = await invalidateOpportunity({
        variables: {
          input: {
            id,
            invalidatedReason: note,
          },
        },
        refetchQueries: ['opportunities'],
      });

      if (res.data.invalidateOpportunity.error) {
        setMessage(res.data.invalidateOpportunity.error.message as string);
      }
    } catch (e) {
      setMessage(`${t('errors.general')}: ${e.message}`);
    }

    setTimeout(() => {
      onOpportunityClick('');
    }, 2000);
  };

  const onDisplay = async (id: string) => {
    try {
      const res = await displayOpportunity({
        variables: {
          input: {
            id,
            source: 'widget',
          },
        },
      });

      if (res.data.displayOpportunity.error) {
        setMessage(res.data.displayOpportunity.error.message as string);
      }
    } catch (e) {
      setMessage(`${t('errors.general')}: ${e.message}`);
    }
  };

  const onCloseOpportunity = () => {
    onOpportunityClick('');
  };

  const { loading, error, data } = useQuery<IUserData>(OPPORTUNITIES, {
    variables: { accountInput },
  });

  if (error) {
    return <EmptyMessage description={t('noOpportunitiesFound')} />;
  }

  if (loading) {
    return <Loader text={t('common:query.fetchingData')} />;
  }

  if (!data || isEmpty(data) || !data.me) {
    return <EmptyMessage description={t('noOpportunitiesFound')} />;
  }

  const {
    me: { opportunities },
  } = data;

  if (opportunities.length === 0) {
    return <EmptyMessage description={t('noOpportunitiesFound')} />;
  }

  let selectedOpportunity;

  // if no opportunity is selected remove from display
  if (selectedId === '') {
    selectedOpportunity = undefined;
  }

  // show selected opportunity
  if (selectedId !== '') {
    selectedOpportunity = opportunities.find(
      (opportunity: IOpportunity) => opportunity.id === selectedId,
    );
  }

  return (
    <>
      {!selectedOpportunity && (
        <div>
          {opportunities.map((opportunity: IOpportunity) => {
            return (
              <OpportunityButton
                key={opportunity.id}
                id={opportunity.id}
                label={opportunity.subject}
                description={`${opportunity.description} - ${opportunity.category}`}
                icon={getIcon(opportunity.category)}
                color={getOpportunityColor(mapCategory(opportunity.category))}
                onClick={(id: string) => onOpportunityClick(id)}
                onDisplayed={(id: string) => onDisplay(id)}
              />
            );
          })}
        </div>
      )}

      {selectedOpportunity && (
        <Opportunity
          key={selectedOpportunity.id}
          id={selectedOpportunity.id}
          title={selectedOpportunity.subject}
          description={selectedOpportunity.description}
          expectedOutcome={selectedOpportunity.expectedOutcome}
          color={getOpportunityColor(mapCategory(selectedOpportunity.category))}
          callToAction={selectedOpportunity.callToAction}
          onExpectedOutcomeClick={(id: string, expectedOutcome: OpportunityExpectedOutcome) =>
            onExpectedOutcomeClick(id, expectedOutcome)
          }
          onInvalidatedClick={(id: string, note: string) => onInvalidatedClick(id, note)}
          onViewOpportunity={(id: string) => onViewOpportunity(id)}
          onCloseOpportunity={() => onCloseOpportunity()}
        />
      )}

      {message && <ErrorMessage>{message}</ErrorMessage>}
    </>
  );
};

export default OpportunitiesList;
