import React, { useState } from "react";
import classNames from "classnames";
import { Moment } from "moment";
import { useConfig } from "../../_util/config-context";
import { ChangeContext } from "../../form/controlled";
import { JumperProps, Jumper } from "../../jumper";
import { CalendarTableType } from "../DateProps";
import { noop } from "../../_util/noop";
import { forwardRefWithStatics } from "../../_util/forward-ref-with-statics";

export enum CellStatus {
  Common,
  Selected,
  InRange,
  InRangeHover,
  RangeStart,
  RangeEnd,
}

export interface TableProps extends React.Props<any> {
  /**
   * 标题渲染
   */
  caption?: React.ReactNode;

  /**
   * Jumper 配置
   */
  jumperOptions?: JumperProps;

  /**
   * table 类型
   */
  type?: CalendarTableType;
}

const Table = forwardRefWithStatics(
  function Table(
    { caption, children, jumperOptions = {}, type }: TableProps,
    ref: React.Ref<HTMLDivElement>
  ) {
    const { classPrefix } = useConfig();
    return (
      <div ref={ref} className={`${classPrefix}-calendar__table`}>
        <div className={`${classPrefix}-calendar__caption`}>{caption}</div>
        <Jumper {...jumperOptions} noBordered showCurrent />
        {/* 日期 */}
        <div className={`${classPrefix}-calendar__row-group`}>
          <div
            className={classNames(`${classPrefix}-calendar__type-wrap`, {
              [`${classPrefix}-calendar__type--month`]: type === "month",
              [`${classPrefix}-calendar__type--year`]: type === "year",
              [`${classPrefix}-calendar__type--quarterly`]: type === "quarter",
            })}
          >
            {children}
          </div>
        </div>
      </div>
    );
  },
  {
    Row: TableRow,
    Cell,
  }
);

Table.displayName = "CalendarBaseTable";

export default Table;

export function TableRow({ children }: { children: React.ReactNode }) {
  const { classPrefix } = useConfig();
  return <div className={`${classPrefix}-calendar__row`}>{children}</div>;
}

TableRow.displayName = "CalendarBaseTableRow";

export interface Cell {
  /**
   * 展示名称
   */
  name: string | number;

  /**
   * 对应日期值
   */
  value?: Moment;

  /**
   * 被选中回调
   */
  onSelect?: (value: Moment, context: ChangeContext) => void;

  /**
   * Outside 日期被选中回调
   */
  onOutsideSelect?: (current: Moment) => void;

  /**
   * Hover 日期被选中回调
   */
  onHoveredChange?: (current: Moment) => void;

  /**
   * 是否为当前时间
   */
  isNow?: boolean;

  /**
   * 是否在当前时间外
   */
  outside?: boolean;

  /**
   * 是否禁用
   */
  disabled?: boolean;

  /**
   * 状态
   */
  status?: CellStatus;

  /**
   * 日历类型
   */
  calendarType?: "date" | "month" | "quarter";
}

export function Cell({
  name,
  value,
  onSelect = noop,
  onOutsideSelect = noop,
  onHoveredChange = noop,
  isNow = false,
  outside = false,
  disabled = false,
  status = CellStatus.Common,
  calendarType = "date",
}: Cell) {
  const { classPrefix } = useConfig();
  const [hovered, setHovered] = useState<boolean>(false);
  return (
    <div
      role="button"
      className={classNames({
        [`${classPrefix}-calendar__cell`]: true,
        [`${classPrefix}-calendar__cell--now`]: isNow,
        [`${classPrefix}-calendar__day--outside`]: outside,
        [`${classPrefix}-calendar__day--in-range`]:
          !outside && status === CellStatus.InRange && calendarType === "date",
        [`${classPrefix}-calendar__day--start is-selected`]:
          !outside &&
          status === CellStatus.RangeStart &&
          calendarType === "date",
        [`${classPrefix}-calendar__day--end is-selected`]:
          !outside && status === CellStatus.RangeEnd && calendarType === "date",

        [`${classPrefix}-calendar__month--in-range`]:
          !outside &&
          status === CellStatus.InRange &&
          ["month", "quarter"].includes(calendarType),
        [`${classPrefix}-calendar__month--start is-selected`]:
          !outside &&
          status === CellStatus.RangeStart &&
          ["month", "quarter"].includes(calendarType),
        [`${classPrefix}-calendar__month--end is-selected`]:
          !outside &&
          status === CellStatus.RangeEnd &&
          ["month", "quarter"].includes(calendarType),
        "is-hover-current": hovered,
        "is-hover": !outside && status === CellStatus.InRangeHover,
        "is-disabled": disabled,
        "is-selected": !outside && status === CellStatus.Selected,
      })}
      onClick={event => {
        if (!disabled) {
          onSelect(value, { event });
          if (outside) {
            onOutsideSelect(value);
          }
        }
      }}
      onMouseEnter={() => {
        if (!disabled) {
          setHovered(true);
          onHoveredChange(value);
        }
      }}
      onMouseLeave={() => {
        setHovered(false);
        onHoveredChange(null);
      }}
    >
      <span>{name}</span>
    </div>
  );
}

Cell.displayName = "CalendarBaseTableCell";
