import { SyncOutlined } from "@ant-design/icons";
import { useQuery } from "@apollo/client/react";
import { Button, Card, Input, Space, Typography } from "antd";
import _ from "lodash";
import queryString from "query-string";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { useLocation, useNavigate } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import AlertComponent from "../../components/alert/alert.component";
import ResponsiveTable from "../../components/responsive-table/responsive-table.component";
import { QUERY_PHONEBOOK_PAGINATED } from "../../graphql/phonebook.queries";
import { selectAuthLevel, selectBodyshop } from "../../redux/user/user.selectors";
import ChatOpenButton from "../../components/chat-open-button/chat-open-button.component";
import { alphaSort } from "../../utils/sorters";
import { HasRbacAccess } from "../../components/rbac-wrapper/rbac-wrapper.component";
import { pageLimit } from "../../utils/config";

const mapStateToProps = createStructuredSelector({
  bodyshop: selectBodyshop,
  authLevel: selectAuthLevel
});

export function PhonebookPageComponent({ bodyshop, authLevel }) {
  const searchParams = queryString.parse(useLocation().search);
  const { page, sortcolumn, sortorder, search, phonebookentry } = searchParams;
  const history = useNavigate();

  const { loading, error, data, refetch } = useQuery(QUERY_PHONEBOOK_PAGINATED, {
    fetchPolicy: "network-only",
    nextFetchPolicy: "network-only",
    variables: {
      search: search || "",
      offset: page ? (page - 1) * pageLimit : 0,
      limit: pageLimit,
      order: [
        {
          [sortcolumn || "lastname"]: sortorder ? (sortorder === "descend" ? "desc" : "asc") : "asc"
        }
      ]
    }
  });

  const { t } = useTranslation();

  if (error) return <AlertComponent title={error.message} type="error" />;

  const handleTableChange = (pagination, filters, sorter) => {
    searchParams.page = pagination.current;
    searchParams.sortcolumn = sorter.columnKey;
    searchParams.sortorder = sorter.order;
    if (filters.status) {
      searchParams.statusFilters = JSON.stringify(_.flattenDeep(filters.status));
    } else {
      delete searchParams.statusFilters;
    }
    history({ search: queryString.stringify(searchParams) });
  };

  const columns = [
    {
      title: t("phonebook.fields.firstname"),
      dataIndex: "firstname",
      key: "firstname",
      sorter: (a, b) => alphaSort(a.firstname, b.firstname),
      sortOrder: sortcolumn === "firstname" && sortorder
    },
    {
      title: t("phonebook.fields.lastname"),
      dataIndex: "lastname",
      key: "lastname",
      sorter: (a, b) => alphaSort(a.lastname, b.lastname),
      sortOrder: sortcolumn === "lastname" && sortorder
    },
    {
      title: t("phonebook.fields.company"),
      dataIndex: "company",
      key: "company",
      sorter: (a, b) => alphaSort(a.company, b.company),
      sortOrder: sortcolumn === "company" && sortorder
    },
    {
      title: t("phonebook.fields.category"),
      dataIndex: "category",
      key: "category",
      sorter: (a, b) => alphaSort(a.category, b.category),
      sortOrder: sortcolumn === "category" && sortorder
    },
    {
      title: t("phonebook.fields.email"),
      dataIndex: "email",
      key: "email"
    },
    {
      title: t("phonebook.fields.phone1"),
      dataIndex: "phone1",
      key: "phone1",
      render: (text) => <ChatOpenButton phone={text} />
    },
    {
      title: t("phonebook.fields.phone2"),
      dataIndex: "phone2",
      key: "phone2",
      render: (text) => <ChatOpenButton phone={text} />
    },
    {
      title: t("phonebook.fields.address1"),
      dataIndex: "address1",
      key: "address1"
    },
    {
      title: t("phonebook.fields.city"),
      dataIndex: "city",
      key: "city"
    }
  ];

  const handleNewPhonebook = () => {
    searchParams.phonebookentry = "new";
    history({ search: queryString.stringify(searchParams) });
  };

  const handleOnRowClick = (record) => {
    if (record) {
      searchParams.phonebookentry = record.id;
      history({ search: queryString.stringify(searchParams) });
    } else {
      delete searchParams.phonebookentry;
      history({ search: queryString.stringify(searchParams) });
    }
  };
  const hasNoAccess = !HasRbacAccess({
    bodyshop,
    authLevel,
    action: "phonebook:edit"
  });

  return (
    <Card
      extra={
        <Space wrap>
          {searchParams.search && (
            <>
              <Typography.Title level={4}>
                {t("general.labels.searchresults", {
                  search: searchParams.search
                })}
              </Typography.Title>
              <Button
                onClick={() => {
                  delete searchParams.search;
                  searchParams.page = 1;
                  history({ search: queryString.stringify(searchParams) });
                }}
              >
                {t("general.actions.clear")}
              </Button>
            </>
          )}
          <Button disabled={hasNoAccess} onClick={handleNewPhonebook}>
            {t("phonebook.actions.new")}
          </Button>
          <Button onClick={() => refetch()} icon={<SyncOutlined />} />
          <Input.Search
            placeholder={searchParams.search || t("general.labels.search")}
            onSearch={(value) => {
              searchParams.search = value;
              searchParams.page = 1;
              history({ search: queryString.stringify(searchParams) });
            }}
            enterButton
          />
        </Space>
      }
    >
      <ResponsiveTable
        loading={loading}
        pagination={{
          placement: "top",
          pageSize: pageLimit,
          current: parseInt(page || 1, 10),
          total: data && data.search_phonebook_aggregate.aggregate.count
        }}
        columns={columns}
        mobileColumnKeys={["firstname", "lastname", "company", "phone1", "phone2"]}
        rowKey="id"
        dataSource={data?.search_phonebook}
        //scroll={{ x: true }}
        onChange={handleTableChange}
        rowSelection={{
          onSelect: handleOnRowClick,
          type: "radio",
          selectedRowKeys: [phonebookentry]
        }}
        onRow={(record) => {
          return {
            onClick: () => {
              handleOnRowClick(record);
            }
          };
        }}
      />
    </Card>
  );
}

export default connect(mapStateToProps, null)(PhonebookPageComponent);
