import * as React from "react";
import { t } from "../../i18next_wrapper";
import { getDevice } from "../../device";
import { destroy, edit, save } from "../../api/crud";
import { ResourceColor } from "../../interfaces";
import { TaggedGenericPointer, TaggedWeedPointer } from "farmbot";
import { ListItem } from "../plants/plant_panel";
import { round, cloneDeep } from "lodash";
import { Row, Col, BlurableInput, ColorPicker } from "../../ui";
import { parseIntInput } from "../../util";
import { UUID } from "../../resources/interfaces";
import { plantAge } from "../plants/map_state_to_props";
import { EditWeedStatus } from "../plants/edit_plant_status";

type PointUpdate =
  Partial<TaggedGenericPointer["body"] | TaggedWeedPointer["body"]>;

export const updatePoint =
  (point: TaggedGenericPointer | TaggedWeedPointer | undefined,
    dispatch: Function) =>
    (update: PointUpdate) => {
      if (point) {
        dispatch(edit(point, update));
        dispatch(save(point.uuid));
      }
    };

export interface EditPointPropertiesProps {
  point: TaggedGenericPointer | TaggedWeedPointer;
  updatePoint(update: PointUpdate): void;
}

export interface AdditionalWeedPropertiesProps {
  point: TaggedWeedPointer;
  updatePoint(update: PointUpdate): void;
}

export const EditPointProperties = (props: EditPointPropertiesProps) =>
  <ul>
    <li>
      <Row>
        <EditPointName
          name={props.point.body.name}
          updatePoint={props.updatePoint} />
        <EditPointColor
          color={props.point.body.meta.color}
          updatePoint={props.updatePoint} />
      </Row>
    </li>
    <ListItem name={t("Location")}>
      <EditPointLocation
        xyLocation={{ x: props.point.body.x, y: props.point.body.y }}
        updatePoint={props.updatePoint} />
    </ListItem>
    <ListItem name={t("Size")}>
      <EditPointRadius
        radius={props.point.body.radius}
        updatePoint={props.updatePoint} />
    </ListItem>
  </ul>;

export const AdditionalWeedProperties = (props: AdditionalWeedPropertiesProps) =>
  <ul className="additional-weed-properties">
    <ListItem name={t("Age")}>
      {`${plantAge(props.point)} ${t("days old")}`}
    </ListItem>
    <ListItem name={t("Status")}>
      <EditWeedStatus weed={props.point} updateWeed={props.updatePoint} />
    </ListItem>
    {Object.entries(props.point.body.meta).map(([key, value]) => {
      switch (key) {
        case "color":
        case "type": return <div key={key}
          className={`meta-${key}-not-displayed`} />;
        case "created_by":
          return <ListItem name={t("Source")} key={key}>
            {SOURCE_LOOKUP()[value || ""] || t("unknown")}
          </ListItem>;
        case "removal_method":
          return <ListItem name={t("Removal method")} key={key}>
            <div className="weed-removal-method-section">
              {REMOVAL_METHODS.map(method =>
                <div className={"weed-removal-method"} key={method}>
                  <input type="radio" name="weed-removal-method"
                    checked={value == method}
                    onChange={() => {
                      const newMeta = cloneDeep(props.point.body.meta);
                      newMeta.removal_method = method;
                      props.updatePoint({ meta: newMeta });
                    }} />
                  <label>{t(method)}</label>
                </div>)}
            </div>
          </ListItem>;
        default:
          return <ListItem name={key} key={key}>
            {value || ""}
          </ListItem>;
      }
    })}
  </ul>;

const REMOVAL_METHODS = ["automatic", "manual"];

const SOURCE_LOOKUP = (): Record<string, string> => ({
  "plant-detection": t("Weed Detector"),
  "farm-designer": t("Farm Designer"),
});

export interface PointActionsProps {
  x: number;
  y: number;
  z: number;
  uuid: UUID;
  dispatch: Function;
}

export const PointActions = ({ x, y, z, uuid, dispatch }: PointActionsProps) =>
  <div className={"point-actions"}>
    <button
      className="fb-button gray no-float"
      type="button"
      title={t("move to location")}
      onClick={() => getDevice().moveAbsolute({ x, y, z })}>
      {t("Move Device to location")}
    </button>
    <button
      className="fb-button red no-float"
      title={t("delete")}
      onClick={() => dispatch(destroy(uuid))}>
      {t("Delete")}
    </button>
  </div>;

export interface EditPointNameProps {
  updatePoint(update: PointUpdate): void;
  name: string;
}

export const EditPointName = (props: EditPointNameProps) =>
  <div className={"point-name-input"}>
    <Col xs={10}>
      <label>{t("Name")}</label>
      <BlurableInput
        type="text"
        name="name"
        value={props.name}
        onCommit={e => props.updatePoint({ name: e.currentTarget.value })} />
    </Col>
  </div>;

export interface EditPointLocationProps {
  updatePoint(update: PointUpdate): void;
  xyLocation: Record<"x" | "y", number>;
}

export const EditPointLocation = (props: EditPointLocationProps) =>
  <Row>
    {["x", "y"].map((axis: "x" | "y") =>
      <Col xs={6} key={axis}>
        <label style={{ marginTop: 0 }}>{t("{{axis}} (mm)", { axis })}</label>
        <BlurableInput
          type="number"
          name={axis}
          value={props.xyLocation[axis]}
          min={0}
          onCommit={e => props.updatePoint({
            [axis]: round(parseIntInput(e.currentTarget.value))
          })} />
      </Col>)}
  </Row>;

export interface EditPointRadiusProps {
  updatePoint(update: PointUpdate): void;
  radius: number;
}

export const EditPointRadius = (props: EditPointRadiusProps) =>
  <Row>
    <Col xs={6}>
      <label style={{ marginTop: 0 }}>{t("radius (mm)")}</label>
      <BlurableInput
        type="number"
        name="radius"
        value={props.radius}
        min={0}
        onCommit={e => props.updatePoint({
          radius: round(parseIntInput(e.currentTarget.value))
        })} />
    </Col>
  </Row>;

export interface EditPointColorProps {
  updatePoint(update: PointUpdate): void;
  color: string | undefined;
}

export const EditPointColor = (props: EditPointColorProps) =>
  <div className={"point-color-input"}>
    <Col xs={2}>
      <ColorPicker
        current={(props.color || "green") as ResourceColor}
        onChange={color => props.updatePoint({ meta: { color } })} />
    </Col>
  </div>;
