/*
 * Copyright (C) 2022 Savoir-faire Linux Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with this program.  If not, see
 * <https://www.gnu.org/licenses/>.
 */
import { SearchRounded } from '@mui/icons-material';
import { InputBase, Stack } from '@mui/material';
import { ChangeEvent, useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { useConversationRequestsQuery, useConversationsSummariesQuery } from '../services/conversationQueries';
import { SquareButton } from './Button';
import ContactSearchResultList from './ContactSearchResultList';
import { ConversationRequestList } from './ConversationRequestList';
import { ConversationSummaryList } from './ConversationSummaryList';
import { PeopleGroupIcon } from './SvgIcon';
import { Tab, TabPanel, TabPanelProps, Tabs, TabsList, TabsProps } from './Tabs';

export default function ConversationList() {
  const { t } = useTranslation();
  const [searchFilter, setSearchFilter] = useState('');

  const handleInputChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {
    setSearchFilter(event.target.value);
  }, []);

  return (
    <Stack>
      <Stack direction="row">
        <InputBase
          type="search"
          placeholder={t('find_users_and_conversations')}
          onChange={handleInputChange}
          startAdornment={<SearchRounded />}
          sx={{
            flexGrow: 1,
          }}
        />
        <SquareButton aria-label="start swarm" Icon={PeopleGroupIcon} />
      </Stack>
      {searchFilter ? <ContactSearchResultList searchFilter={searchFilter} /> : <ConversationTabs />}
    </Stack>
  );
}

const ConversationTabs = () => {
  const summariesTabIndex = 0;
  const invitationsTabIndex = 1;
  const { t } = useTranslation();
  const conversationRequestsQuery = useConversationRequestsQuery();
  const conversationRequestsLength = conversationRequestsQuery.data?.length;

  const [isShowingTabMenu, setIsShowingTabMenu] = useState(false);
  const [tabIndex, setTabIndex] = useState(summariesTabIndex);

  useEffect(() => {
    const newIsShowingTabMenu = !!conversationRequestsLength;
    setIsShowingTabMenu(newIsShowingTabMenu);
    if (!newIsShowingTabMenu) {
      setTabIndex(summariesTabIndex);
    }
  }, [conversationRequestsLength]);

  const onChange = useCallback<NonNullable<TabsProps['onChange']>>((_event, value) => {
    if (typeof value === 'number') {
      setTabIndex(value);
    }
  }, []);

  return (
    <Tabs defaultValue={summariesTabIndex} value={tabIndex} onChange={onChange}>
      {isShowingTabMenu && (
        <TabsList>
          <Tab>{t('conversations')}</Tab>
          <Tab>
            {t('invitations')} {conversationRequestsLength}
          </Tab>
        </TabsList>
      )}
      <SummariesTabPanel value={summariesTabIndex} />
      <InvitationsTabPanel value={invitationsTabIndex} />
    </Tabs>
  );
};

const SummariesTabPanel = (props: TabPanelProps) => {
  const conversationsSummariesQuery = useConversationsSummariesQuery();
  const conversationsSummaries = conversationsSummariesQuery.data || [];

  return (
    <TabPanel {...props}>
      <ConversationSummaryList conversationsSummaries={conversationsSummaries} />
    </TabPanel>
  );
};

const InvitationsTabPanel = (props: TabPanelProps) => {
  return (
    <TabPanel {...props}>
      <ConversationRequestList />
    </TabPanel>
  );
};
