// Copyright (c) 2021 Terminus, Inc.
//
// This program is free software: you can use, redistribute, and/or modify
// it under the terms of the GNU Affero General Public License, version 3
// or later ("AGPL"), as published by the Free Software Foundation.
//
// 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.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import React from 'react';
import { Spin } from 'antd';
import { CommonRangePicker, BoardGrid } from 'common';
import { useUpdate } from 'common/use-hooks';
import { getDashboard } from 'apiManagePlatform/services/api-access';
import { get, isString, merge, reduce, values, isEmpty } from 'lodash';
import { getTimeSpan } from 'common/utils';
import { getVariableStr } from 'cmp/common/utils';
import { createLoadDataFn } from 'cmp/common/custom-dashboard/data-loader';

interface IState {
  layout: Array<Record<string, any>>;
  boardConfig: Array<Record<string, any>>;
  timeSpan: ITimeSpan;
  loading: boolean;
}

interface IProps {
  type: API_ACCESS.DashboardType;
  extraQuery?: Record<string, any>;
}

const Chart = ({ type, extraQuery = {} }: IProps) => {
  const [{ layout, boardConfig, timeSpan, loading }, updater] = useUpdate<IState>({
    layout: [],
    boardConfig: [],
    timeSpan: getTimeSpan(),
    loading: false,
  });
  React.useEffect(() => {
    updater.loading(true);
    getDashboard({ type })
      .then(({ data }: any) => updater.boardConfig(data.viewConfig || []))
      .finally(() => {
        updater.loading(false);
      });
  }, [type, updater]);
  React.useEffect(() => {
    updater.timeSpan(getTimeSpan());
  }, [extraQuery, updater]);
  const query = React.useMemo(() => {
    return {
      ...extraQuery,
      start: timeSpan.startTimeMs,
      end: timeSpan.endTimeMs,
    };
  }, [extraQuery, timeSpan.endTimeMs, timeSpan.startTimeMs]);
  React.useEffect(() => {
    const { start, end, ...restQuery } = query;
    const flag = !isEmpty(restQuery) && values(restQuery).every((t) => !!t);
    if (!flag) {
      return;
    }
    const _layout = boardConfig.map((viewItem) => {
      const filters = get(viewItem, 'view.api.extraData.filters');
      const _viewItem = merge({}, viewItem, {
        view: {
          api: {
            query: {
              start,
              end,
              ...reduce(
                filters,
                (acc, { value, method, tag }) => {
                  const matchQuery = isString(value) ? getVariableStr(value) : undefined;
                  return {
                    ...acc,
                    [`${method}_${tag}`]: matchQuery ? restQuery[matchQuery] : value.split(','),
                  };
                },
                {},
              ),
            },
          },
        },
      });
      const { api, chartType } = _viewItem.view as any;

      return merge({}, viewItem, { view: { loadData: createLoadDataFn(api, chartType) } });
    });
    updater.layout(_layout);
  }, [boardConfig, query, updater]);

  return (
    <Spin spinning={loading}>
      <CommonRangePicker
        className="mb-3"
        defaultTime={[timeSpan.startTimeMs, timeSpan.endTimeMs]}
        onOk={(v) => updater.timeSpan(v)}
      />
      <BoardGrid.Pure layout={layout} />
    </Spin>
  );
};

export default Chart;