import { utc, duration, ISO_8601 } from "moment";
import React, { Component } from "react";
import { connect } from "react-redux";
import { Redirect } from "react-router-dom";
import { Header, Label, Loader } from "semantic-ui-react";

import {
  setFormEmployeeUUID,
  setFormPriceUUID,
  setFormShiftStartTime,
  setFormShiftDuration,
  setFormShiftNote,
  setClearCShiftState,
  setFormShiftDates,
  setCShiftUUID
} from "../../../actions/cShift/reducer.actions";
import {
  getCShiftRequest,
  editCShiftRequest
} from "../../../actions/cShift/saga.actions";
import { ClientShiftFormView } from "./ClientShiftFormView";
import { getEmployeeFromPrice } from "./ClientShiftShared";

class ClientEditShiftForm extends Component {
  constructor(props) {
    super(props);

    const { cShiftRequestSuccess, selfUser } = this.props;
    if (selfUser.client && cShiftRequestSuccess.uuid) {
      const employee = getEmployeeFromPrice(
        cShiftRequestSuccess.price,
        selfUser
      );
      const startTime = utc(cShiftRequestSuccess.set_start, ISO_8601).local();
      const endTime = utc(cShiftRequestSuccess.set_end, ISO_8601).local();
      this.props.dispatch(setCShiftUUID(cShiftRequestSuccess.uuid));
      this.props.dispatch(setFormShiftDates([startTime]));
      this.props.dispatch(setFormShiftStartTime(startTime));
      this.props.dispatch(
        setFormShiftDuration(
          duration(endTime - startTime, "milliseconds").as("minutes")
        )
      );
      this.props.dispatch(setFormEmployeeUUID(employee.uuid));
      this.props.dispatch(setFormShiftNote(cShiftRequestSuccess.description));
      this.props.dispatch(setFormPriceUUID(cShiftRequestSuccess.price));
    }
  }

  changeSelectedEmployee = (e, { value }) => {
    if (value !== this.props.employeeUUID) {
      this.props.dispatch(setFormPriceUUID(""));
    }
    this.props.dispatch(setFormEmployeeUUID(value));
  };

  changeSelectedPrice = (e, { value }) => {
    this.props.dispatch(setFormPriceUUID(value));
  };

  /**
   * change handler for shift start time selector.
   * @param momentTime - instance of moment (but we only care about the time)
   */
  changeShiftStartTime = momentTime => {
    this.props.dispatch(setFormShiftStartTime(momentTime));
  };

  changeShiftDuration = (e, { value }) => {
    this.props.dispatch(setFormShiftDuration(value));
  };

  changeShiftNote = event => {
    this.props.dispatch(setFormShiftNote(event.target.value));
  };

  /**
   * change handler for shift date selector
   * @param momentDate - instance of moment (but we only care about the day)
   */
  handleSelectDate = momentDate => {
    this.props.dispatch(setFormShiftDates([momentDate]));
  };

  onSubmitShifts = event => {
    event.preventDefault();
    // change this into interable cshift post request bodies
    const {
      cShiftUUID,
      priceUUID,
      startTime,
      duration,
      note,
      shiftDates
    } = this.props;
    const postRequestBodies = [];
    for (let shiftDateString in shiftDates) {
      const dynamicStartTime = utc(startTime);
      const startDate = shiftDates[shiftDateString];
      dynamicStartTime.set({
        year: startDate.get("year"),
        month: startDate.get("month"),
        date: startDate.get("date")
      });
      const dynamicEndTime = utc(dynamicStartTime);
      dynamicEndTime.add(duration, "minutes");
      postRequestBodies.push({
        get_price_uuid: priceUUID,
        set_start: dynamicStartTime.format(),
        set_end: dynamicEndTime.format(),
        description: note ? note : undefined
      });
    }
    this.props.dispatch(
      editCShiftRequest({ ...postRequestBodies[0], uuid: cShiftUUID })
    );
  };

  render() {
    const {
      isSendingCShiftRequest,
      cShiftRequestErrors,
      cShiftRequestSuccess,
      selfUser,
      employeeUUID,
      priceUUID,
      startTime,
      duration,
      note,
      shiftDates,
      cShiftUUID
    } = this.props;

    if (!selfUser.client) {
      return <Redirect to="/" />;
    }
    if (cShiftUUID === true) {
      return <Redirect to="/user/profile/client/shifts" />;
    }

    const employeeChoices = selfUser.client.employees
      // TODO: ugly edit of state changed employee
      .filter(employee => !employee.deleted && !!employee.approved)
      .map(({ uuid, provider }) => ({
        key: uuid,
        value: uuid,
        text: provider.email
      }));

    const priceChoices = [];
    if (employeeUUID) {
      const employee = selfUser.client.employees.find(emp => {
        return emp && emp.uuid === employeeUUID;
      });
      priceChoices.push(
        ...employee.prices
          .filter(price => !price.deleted)
          .map(({ amount, uuid, work_type }) => ({
            key: uuid,
            value: uuid,
            text: `${work_type.label} ($${amount}/hr)`,
            content: (
              <Header>
                <Label
                  circular
                  empty
                  style={{
                    backgroundColor: work_type.color,
                    borderColor: work_type.color
                  }}
                />
                {work_type.label}
                <Header.Subheader
                  style={{ paddingLeft: "2em" }}
                  content={`Hourly Rate: ${amount}`}
                />
              </Header>
            )
          }))
      );
    }

    const selectedShiftDates = Object.keys(shiftDates).map(
      key => shiftDates[key]
    );
    return (
      <ClientShiftFormView
        isSendingCShiftRequest={isSendingCShiftRequest}
        cShiftRequestErrors={cShiftRequestErrors}
        cShiftRequestSuccess={!!cShiftRequestSuccess.length}
        user={selfUser}
        employeeChoices={employeeChoices}
        priceChoices={priceChoices}
        employeeUUID={employeeUUID}
        priceUUID={priceUUID}
        startTime={startTime}
        duration={duration}
        note={note || ""}
        selectedShiftDates={selectedShiftDates}
        changeSelectedEmployee={this.changeSelectedEmployee}
        changeSelectedPrice={this.changeSelectedPrice}
        changeShiftStartTime={this.changeShiftStartTime}
        changeShiftDuration={this.changeShiftDuration}
        changeShiftNote={this.changeShiftNote}
        handleSelectDate={this.handleSelectDate}
        onSubmitShifts={this.onSubmitShifts}
        isEditing={true}
      />
    );
  }
}

function mapStateToProps(state) {
  return { ...state.cShift, selfUser: state.user.selfUser };
}

class EditClientShiftWrapper extends Component {
  constructor(props) {
    super(props);
    this.props.dispatch(setClearCShiftState());
    this.props.dispatch(
      getCShiftRequest({ uuid: this.props.match.params.shiftUUID })
    );
  }

  render() {
    const { cShiftRequestSuccess } = this.props;
    if (cShiftRequestSuccess.uuid) {
      return <ClientEditShiftForm {...this.props} />;
    } else {
      return <Loader />;
    }
  }
}

export default connect(mapStateToProps)(EditClientShiftWrapper);
