import * as React from "react";
import moment from "moment";
import produce from "immer";

import {
  useTranslation,
  DataItemHistoryOptionsInterface,
  DataItemHistorySelectionInterface,
  useDeepCompareEffect,
  DataItemDimensionHistoryOptionsInterface,
} from "..";
import {
  Radio,
  DatePicker,
  InputNumber,
  Checkbox,
  Select,
  Row,
  Col,
} from "antd";

const COL_STYLE: React.CSSProperties = { marginBottom: 24 };
const INPUT_STYLE: React.CSSProperties = { width: "100%" };

interface Props {
  value: DataItemDimensionHistoryOptionsInterface;
  onChange: (nextValue: DataItemDimensionHistoryOptionsInterface) => void;
  options?: DataItemHistorySelectionInterface;
  style?: React.CSSProperties;
}

export function DataItemHistoryOptionsPicker({
  style,
  options = {},
  value = {},
  onChange,
}: Props) {
  const [t] = useTranslation(["opendash"]);

  useDeepCompareEffect(() => {
    onChange(
      produce(value, (draft) => {
        if (!options.live) {
          draft.live = false;
        } else if (options.live && options.liveRequired) {
          draft.live = true;
        }

        if (!options.history) {
          Object.assign(draft, {
            historyType: undefined,
            start: undefined,
            end: undefined,
            unit: undefined,
            value: undefined,
            aggregation: undefined,
          });
        } else if (
          options.history &&
          options.historyRequired &&
          !draft.historyType
        ) {
          draft.historyType = "absolute";
        }
      })
    );
  }, [value]);

  React.useEffect(() => {
    if (value?.historyType === "absolute") {
      onChange(
        merge(value, {
          start: moment().subtract(7, "day").startOf("day").valueOf(),
          end: Date.now(),
          unit: undefined,
          value: undefined,
        })
      );
    } else if (value?.historyType === "relative") {
      onChange(
        merge(value, {
          start: undefined,
          end: undefined,
          unit: "week",
          value: 1,
        })
      );
    } else {
      onChange(
        merge(value, {
          start: undefined,
          end: undefined,
          unit: undefined,
          value: undefined,
        })
      );
    }
  }, [value?.historyType]);

  return (
    <>
      <Row gutter={16}>
        <Col style={COL_STYLE} span={24}>
          <Checkbox
            checked={value.live}
            disabled={!options?.live || options?.liveRequired}
            onChange={(e) => {
              onChange(
                merge(value, {
                  live: e.target.checked,
                })
              );
            }}
          >
            {t("monitoring.history_options.live_enabled")}
          </Checkbox>
        </Col>
      </Row>

      <Row gutter={16}>
        <Col style={COL_STYLE} span={24}>
          <Checkbox
            checked={!!value.historyType}
            disabled={!options?.history || options?.historyRequired}
            onChange={(e) => {
              onChange(
                merge(value, {
                  historyType: e.target.checked ? "absolute" : undefined,
                })
              );
            }}
          >
            {t("monitoring.history_options.history_enabled")}
          </Checkbox>
        </Col>
      </Row>

      <Row gutter={16}>
        <Col style={COL_STYLE} span={24}>
          <Radio.Group
            disabled={!value.historyType}
            size="small"
            value={value.historyType}
            onChange={(e) => {
              onChange(
                merge(value, {
                  historyType: e.target.value,
                })
              );
            }}
          >
            <Radio.Button value="absolute">
              {t("monitoring.history_options.type_absolute")}
            </Radio.Button>
            <Radio.Button value="relative">
              {t("monitoring.history_options.type_relative")}
            </Radio.Button>
          </Radio.Group>
        </Col>
      </Row>

      {value.historyType === "relative" && (
        <Row gutter={16}>
          <Col style={COL_STYLE} span={12}>
            <InputNumber
              disabled={!value.historyType}
              style={INPUT_STYLE}
              min={1}
              value={value.value}
              onChange={(nextValue) =>
                onChange(
                  merge(value, {
                    value: Math.floor(Math.max(nextValue, 1)),
                  })
                )
              }
            />
          </Col>
          <Col style={COL_STYLE} span={12}>
            <Select
              disabled={!value.historyType}
              style={INPUT_STYLE}
              value={value.unit}
              onChange={(unit) => {
                onChange(
                  merge(value, {
                    unit,
                  })
                );
              }}
            >
              <Select.Option value="day">
                {t("ui.day", { count: value.value })}
              </Select.Option>
              <Select.Option value="week">
                {t("ui.week", { count: value.value })}
              </Select.Option>
              <Select.Option value="month">
                {t("ui.month", { count: value.value })}
              </Select.Option>
              <Select.Option value="year">
                {t("ui.year", { count: value.value })}
              </Select.Option>
            </Select>
          </Col>
        </Row>
      )}

      {value.historyType === "absolute" && (
        <Row gutter={16}>
          <Col style={COL_STYLE} span={24}>
            <DatePicker.RangePicker
              disabled={!value.historyType}
              allowClear={false}
              placeholder={t("ui.select_date_range")}
              style={style}
              value={[moment(value?.start), moment(value?.end)]}
              onChange={(nextValue) =>
                onChange(
                  merge(value, {
                    start: nextValue[0].valueOf(),
                    end: nextValue[1].valueOf(),
                    unit: undefined,
                    value: undefined,
                  })
                )
              }
            />
          </Col>
        </Row>
      )}

      <Row gutter={16}>
        <Col style={COL_STYLE} span={24}>
          <Select
            style={INPUT_STYLE}
            disabled={!options?.aggregation || options?.aggregationRequired}
            value={
              (value as DataItemDimensionHistoryOptionsInterface)
                .aggregationType ?? "none"
            }
            onChange={(aggregation) => {
              onChange(
                mergeDim(value, {
                  aggregationType: aggregation === "none" ? null : aggregation,
                })
              );
            }}
          >
            <Select.Option value="none">
              {t("monitoring.history_options.aggregation_none")}
            </Select.Option>

            <Select.Option value="sum">
              {t("monitoring.history_options.aggregation_sum")}
            </Select.Option>

            <Select.Option value="mean">
              {t("monitoring.history_options.aggregation_mean")}
            </Select.Option>

            <Select.Option value="max">
              {t("monitoring.history_options.aggregation_max")}
            </Select.Option>

            <Select.Option value="min">
              {t("monitoring.history_options.aggregation_min")}
            </Select.Option>

            <Select.Option value="count">
              {t("monitoring.history_options.aggregation_count")}
            </Select.Option>
          </Select>
        </Col>
      </Row>
    </>
  );
}

function merge(
  current: DataItemHistoryOptionsInterface,
  update: Partial<DataItemHistoryOptionsInterface>
): DataItemHistoryOptionsInterface {
  return Object.assign({}, current || {}, update);
}

function mergeDim(
  current: DataItemDimensionHistoryOptionsInterface,
  update: Partial<DataItemDimensionHistoryOptionsInterface>
): DataItemDimensionHistoryOptionsInterface {
  return Object.assign({}, current || {}, update);
}
