import {BranchesOutlined, ExclamationCircleFilled, PauseCircleOutlined, SyncOutlined,} from "@ant-design/icons";
import {useQuery} from "@apollo/client";
import {Button, Card, Grid, Input, Space, Table, Tooltip, Typography} from "antd";
import queryString from "query-string";
import React, {useEffect, useState} from "react";
import {useTranslation} from "react-i18next";
import {connect} from "react-redux";
import {Link, useHistory, useLocation} from "react-router-dom";
import {createStructuredSelector} from "reselect";
import {QUERY_ALL_ACTIVE_JOBS_PAGINATED} from "../../graphql/jobs.queries";
import {selectBodyshop} from "../../redux/user/user.selectors";
import {onlyUnique} from "../../utils/arrayHelper";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
import AlertComponent from "../alert/alert.component";
import ChatOpenButton from "../chat-open-button/chat-open-button.component";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
import {flattenDeep} from "lodash";
import { pageLimit } from '../../utils/config';
import axios from "axios";

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

const mapDispatchToProps = () => ({
});

export function JobsList({bodyshop,}) {
    const search = queryString.parse(useLocation().search);
    const [openSearchResults, setOpenSearchResults] = useState([]);
    const [searchLoading, setSearchLoading] = useState(false);
    const {page, selected, sortorder, sortcolumn} = search;

    const selectedBreakpoint = Object.entries(Grid.useBreakpoint())
        .filter((screen) => !!screen[1])
        .slice(-1)[0];

    const {loading, error, data, refetch} = useQuery(QUERY_ALL_ACTIVE_JOBS_PAGINATED, {
        variables: {
            offset: page ? (page - 1) * pageLimit : 0,
            limit: pageLimit,
            statuses: bodyshop.md_ro_statuses.active_statuses || ["Open", "Open*"],
            order: [
                {
                    [sortcolumn || "ro_number"]:
                        sortorder && sortorder !== "false"
                            ? (sortorder === "descend"
                                ? "desc"
                                : "asc")
                            : "desc",
                },
            ],
        },
        fetchPolicy: "network-only",
        nextFetchPolicy: "network-only",
    });

    const total = data?.jobs_aggregate?.aggregate?.count || 0;

    const [state, setState] = useState({
        filteredInfo: {text: ""},
    });

    const {t} = useTranslation();
    const history = useHistory();

    const jobs = data?.jobs || [];

    const handleTableChange = (pagination, filters, sorter) => {
        // TODO: Is this needed?
        setState({...state, filteredInfo: filters});

        search.page = pagination.current;
        search.sortcolumn = sorter.column && sorter.column.key;
        search.sortorder = sorter.order;

        if (filters.status) {
            search.statusFilters = JSON.stringify(flattenDeep(filters.status));
        } else {
            delete search.statusFilters;
        }

        history.push({search: queryString.stringify(search)});
    };

    useEffect(() => {
        if (search.search && search.search.trim() !== "") {
            searchJobs().catch(e => {
                console.error('Something went wrong searching for jobs in the job-list component', e);
            });
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

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

    async function searchJobs(value) {
        try {
            setSearchLoading(true);
            const searchData = await axios.post("/search", {
                search: value || search.search,
                index: "jobs",
            });
            setOpenSearchResults(searchData.data.hits.hits.map((s) => s._source));
        } catch (error) {
            console.log("Error while fetching search results", error);
        } finally {
            setSearchLoading(false);
        }
    }

    const handleOnRowClick = (record) => {
        if (record) {
            if (record.id) {
                history.push({
                    search: queryString.stringify({
                        ...search,
                        selected: record.id,
                    }),
                });
            }
        }
    };

    const columns = [
        {
            title: t("jobs.fields.ro_number"),
            dataIndex: "ro_number",
            key: "ro_number",
            sorter: true,
            sortOrder:
                sortcolumn === "ro_number" && sortorder,

            render: (text, record) => (
                <Link
                    to={"/manage/jobs/" + record.id}
                    onClick={(e) => e.stopPropagation()}
                >
                    <Space>
                        {record.ro_number || t("general.labels.na")}
                        {record.production_vars && record.production_vars.alert ? (
                            <ExclamationCircleFilled className="production-alert"/>
                        ) : null}
                        {record.suspended && (
                            <PauseCircleOutlined style={{color: "orangered"}}/>
                        )}
                        {record.iouparent && (
                            <Tooltip title={t("jobs.labels.iou")}>
                                <BranchesOutlined style={{color: "orangered"}}/>
                            </Tooltip>
                        )}
                    </Space>
                </Link>
            ),
        },
        {
            title: t("jobs.fields.owner"),
            dataIndex: "owner",
            key: "owner",
            ellipsis: true,
            responsive: ["md"],
            sorter: false,
            sortOrder: sortcolumn === "owner" && sortorder,
            render: (text, record) => {
                return record.ownerid ? (
                    <Link
                        to={"/manage/owners/" + record.ownerid}
                        onClick={(e) => e.stopPropagation()}
                    >
                        <OwnerNameDisplay ownerObject={record}/>
                    </Link>
                ) : (
                    <span>
            <OwnerNameDisplay ownerObject={record}/>
          </span>
                );
            },
        },
        {
            title: t("jobs.fields.ownr_ph1"),
            dataIndex: "ownr_ph1",
            key: "ownr_ph1",
            ellipsis: true,
            responsive: ["md"],
            render: (text, record) => (
                <ChatOpenButton phone={record.ownr_ph1} jobid={record.id}/>
            ),
        },
        {
            title: t("jobs.fields.ownr_ph2"),
            dataIndex: "ownr_ph2",
            key: "ownr_ph2",
            ellipsis: true,
            responsive: ["md"],
            render: (text, record) => (
                <ChatOpenButton phone={record.ownr_ph2} jobid={record.id}/>
            ),
        },

        {
            title: t("jobs.fields.status"),
            dataIndex: "status",
            key: "status",
            ellipsis: true,
            sorter: true,
            sortOrder:
                sortcolumn === "status" && sortorder,
            filters:
                (jobs &&
                    jobs
                        .map((j) => j.status)
                        .filter(onlyUnique)
                        .map((s) => {
                            return {
                                text: s || "No Status*",
                                value: [s],
                            };
                        })) ||
                [],
            onFilter: (value, record) => value.includes(record.status),
        },
        {
            title: t("jobs.fields.vehicle"),
            dataIndex: "vehicle",
            key: "vehicle",
            ellipsis: true,
            render: (text, record) => {
                return record.vehicleid ? (
                    <Link
                        to={"/manage/vehicles/" + record.vehicleid}
                        onClick={(e) => e.stopPropagation()}
                    >
                        {`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${
                            record.v_model_desc || ""
                        }`}
                    </Link>
                ) : (
                    <span>{`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${
                        record.v_model_desc || ""
                    }`}</span>
                );
            },
        },
        {
            title: t("vehicles.fields.plate_no"),
            dataIndex: "plate_no",
            key: "plate_no",
            ellipsis: true,
            responsive: ["md"],
            sorter: true,
            sortOrder:
                sortcolumn === "plate_no" && sortorder,
        },
        {
            title: t("jobs.fields.clm_no"),
            dataIndex: "clm_no",
            key: "clm_no",
            ellipsis: true,
            responsive: ["md"],
            sorter: true,
            sortOrder:
                sortcolumn === "clm_no" && sortorder,
            render: (text, record) =>
                `${record.clm_no || ""}${
                    record.po_number ? ` (PO: ${record.po_number})` : ""
                }`,
        },
        {
            title: t("jobs.fields.ins_co_nm"),
            dataIndex: "ins_co_nm",
            key: "ins_co_nm",
            ellipsis: true,
            filters:
                (jobs &&
                    jobs
                        .map((j) => j.ins_co_nm)
                        .filter(onlyUnique)
                        .map((s) => {
                            return {
                                text: s,
                                value: [s],
                            };
                        })) ||
                [],
            onFilter: (value, record) => value.includes(record.ins_co_nm),
            responsive: ["md"],
        },
        {
            title: t("jobs.fields.clm_total"),
            dataIndex: "clm_total",
            key: "clm_total",
            responsive: ["md"],
            ellipsis: true,
            sorter: true,
            sortOrder:
                sortcolumn === "clm_total" && sortorder,
            render: (text, record) => (
                <CurrencyFormatter>{record.clm_total}</CurrencyFormatter>
            ),
        },
        {
            title: t("jobs.labels.estimator"),
            dataIndex: "jobs.labels.estimator",
            key: "jobs.labels.estimator",
            ellipsis: true,
            responsive: ["xl"],
            filterSearch: true,
            filters:
                (jobs &&
                    jobs
                        .map((j) => `${j.est_ct_fn || ""} ${j.est_ct_ln || ""}`.trim())
                        .filter(onlyUnique)
                        .map((s) => {
                            return {
                                text: s || "N/A",
                                value: [s],
                            };
                        })) ||
                [],
            onFilter: (value, record) =>
                value.includes(
                    `${record.est_ct_fn || ""} ${record.est_ct_ln || ""}`.trim()
                ),
            render: (text, record) =>
                `${record.est_ct_fn || ""} ${record.est_ct_ln || ""}`.trim(),
        },
        {
            title: t("jobs.fields.comment"),
            dataIndex: "comment",
            key: "comment",
            ellipsis: true,
            responsive: ["md"],
        },
        // {
        //   title: t("jobs.fields.owner_owing"),
        //   dataIndex: "owner_owing",
        //   key: "owner_owing",
        //   responsive: ["md"],
        //   render: (text, record) => (
        //     <CurrencyFormatter>{record.owner_owing}</CurrencyFormatter>
        //   ),
        // },
    ];

    const scrollMapper = {
        xs: true,
        sm: true,
        md: true,
        lg: "100%",
        xl: "100%",
        xxl: "100%",
    };

    return (
        <Card
            title={t("titles.bc.jobs-active")}
            extra={
                <Space wrap>
                    {search.search && (
                        <>
                            <Typography.Title level={4}>
                                {t("general.labels.searchresults", { search: search.search })}
                            </Typography.Title>
                            <Button
                                onClick={() => {
                                    delete search.search;
                                    delete search.page;
                                    history.push({ search: queryString.stringify(search) });
                                }}
                            >
                                {t("general.actions.clear")}
                            </Button>
                        </>
                    )}
                    <Button onClick={() => refetch()}>
                        <SyncOutlined />
                    </Button>
                    <Input.Search
                        placeholder={search.search || t("general.labels.search")}
                        onSearch={(value) => {
                            search.search = value;
                            history.push({ search: queryString.stringify(search) });
                            searchJobs(value);
                        }}
                        loading={loading || searchLoading}
                        enterButton
                    />
                </Space>
            }
        >
            <Table
                loading={loading || searchLoading }
                pagination={
                    search?.search
                        ? {
                            pageSize: pageLimit,
                            showSizeChanger: false,

                        }
                        : {
                            pageSize: pageLimit,
                            current: parseInt(page || 1),
                            total: total,
                            showSizeChanger: false,
                        }
                }
                columns={columns}
                rowKey="id"
                dataSource={search?.search ? openSearchResults : jobs}
                scroll={{
                    x: selectedBreakpoint ? scrollMapper[selectedBreakpoint[0]] : "100%",
                }}
                rowSelection={{
                    onSelect: (record) => {
                        handleOnRowClick(record);
                    },
                    selectedRowKeys: [selected],
                    type: "radio",
                }}
                onChange={handleTableChange}
                onRow={(record) => {
                    return {
                        onClick: () => {
                            handleOnRowClick(record);
                        },
                    };
                }}
            />
        </Card>
    );
}

export default connect(mapStateToProps, mapDispatchToProps)(JobsList);
