import { utc, ISO_8601, duration } from "moment";
import React, { Component, Fragment } from "react";
import { connect } from "react-redux";
import { Redirect, Link } from "react-router-dom";
import {
  Button,
  Container,
  Dropdown,
  Header,
  Item,
  Segment,
  Pagination,
  Popup,
  Loader,
  Label,
  List,
  Message
} from "semantic-ui-react";
import {
  setCShiftPage,
  setCShiftApprovalFilter,
  setCShiftCompletedFilter,
  setCShiftProviderFilter,
  setCShiftWorkTypeFilter
} from "../../../actions/cShift/reducer.actions";
import {
  getCShiftsRequest,
  deleteCShiftRequest,
  editCShiftRequest
} from "../../../actions/cShift/saga.actions";
import { getEmployeeFromPrice, getPriceFromPrice } from "./ClientShiftShared";
import ShiftLabel from "../../Shared/ShiftLabel";

class ClientShifts extends Component {
  constructor(props) {
    super(props);
    this.state = {
      pageSize: 10 // client can't control this, but set here just in case
    };
  }

  componentWillMount = () => {
    this.props.dispatch(
      getCShiftsRequest({
        page: this.props.page,
        provider_approved: this.props.approvalFilter,
        completed: this.props.completedFilter,
        manage: this.props.providerFilter,
        work_type: this.props.workTypeFilter,
        page_size: this.state.pageSize
      })
    );
  };

  handlePaginationChange = (event, { activePage }) => {
    this.props.dispatch(
      getCShiftsRequest({
        page: activePage,
        provider_approved: this.props.approvalFilter,
        manage: this.props.providerFilter,
        work_type: this.props.workTypeFilter,
        page_size: this.state.pageSize
      })
    );
    this.props.dispatch(setCShiftPage(activePage));
  };

  handleChangeApprovalFilter = (event, { value }) => {
    this.props.dispatch(
      getCShiftsRequest({
        page: 1,
        provider_approved: value,
        completed: this.props.completedFilter,
        manage: this.props.providerFilter,
        work_type: this.props.workTypeFilter,
        page_size: this.state.pageSize
      })
    );
    this.props.dispatch(setCShiftApprovalFilter(value));
    this.props.dispatch(setCShiftPage(1));
  };

  handleChangeCompletedFilter = (event, { value }) => {
    this.props.dispatch(
      getCShiftsRequest({
        page: 1,
        provider_approved: this.props.approvalFilter,
        completed: value,
        manage: this.props.providerFilter,
        work_type: this.props.workTypeFilter,
        page_size: this.state.pageSize
      })
    );
    this.props.dispatch(setCShiftCompletedFilter(value));
    this.props.dispatch(setCShiftPage(1));
  };

  handleChangeProviderFilter = (event, { value }) => {
    this.props.dispatch(
      getCShiftsRequest({
        page: 1,
        provider_approved: this.props.approvalFilter,
        completed: this.props.completedFilter,
        manage: value,
        work_type: this.props.workTypeFilter,
        page_size: this.state.pageSize
      })
    );
    this.props.dispatch(setCShiftProviderFilter(value));
    this.props.dispatch(setCShiftPage(1));
  };

  handleChangeWorkTypeFilter = (event, { value }) => {
    this.props.dispatch(
      getCShiftsRequest({
        page: 1,
        provider_approved: this.props.approvalFilter,
        completed: this.props.completedFilter,
        manage: this.props.manageFilter,
        work_type: value,
        page_size: this.state.pageSize
      })
    );
    this.props.dispatch(setCShiftWorkTypeFilter(value));
    this.props.dispatch(setCShiftPage(1));
  };

  deleteCShift = uuid => {
    this.props.dispatch(deleteCShiftRequest(uuid));
  };

  approveHoursCShift = async cshift => {
    const {
      set_start: approved_start,
      set_end: approved_end,
      price: get_price_uuid
    } = cshift;
    this.props.dispatch(
      editCShiftRequest({
        uuid: cshift.uuid,
        get_price_uuid,
        approved_start,
        approved_end,
        set_start: null,
        set_end: null
      })
    );
    await new Promise(resolve => setTimeout(resolve, 500));
    this.props.dispatch(
      getCShiftsRequest({
        page: this.props.page,
        provider_approved: this.props.approvalFilter,
        completed: this.props.completedFilter,
        manage: this.props.providerFilter,
        work_type: this.props.workTypeFilter,
        page_size: this.state.pageSize
      })
    );
  };

  render() {
    const {
      isSendingCShiftRequest,
      cShiftRequestSuccess,
      selfUser,
      page,
      approvalFilter,
      completedFilter,
      providerFilter,
      workTypeFilter
    } = this.props;
    const { pageSize } = this.state;
    if (selfUser.client) {
      return (
        <ClientShiftsView
          isSendingCShiftRequest={isSendingCShiftRequest}
          cShiftRequestSuccess={cShiftRequestSuccess}
          page={page}
          approvalFilter={approvalFilter}
          completedFilter={completedFilter}
          providerFilter={providerFilter}
          workTypeFilter={workTypeFilter}
          pageSize={pageSize}
          user={selfUser}
          handlePaginationChange={this.handlePaginationChange}
          handleChangeApprovalFilter={this.handleChangeApprovalFilter}
          handleChangeCompletedFilter={this.handleChangeCompletedFilter}
          handleChangeProviderFilter={this.handleChangeProviderFilter}
          handleChangeWorkTypeFilter={this.handleChangeWorkTypeFilter}
          deleteCShift={this.deleteCShift}
          approveHoursCShift={this.approveHoursCShift}
        />
      );
    } else {
      return <Redirect to="/" />;
    }
  }
}

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

const ClientShiftsView = ({
  isSendingCShiftRequest,
  cShiftRequestSuccess,
  user,
  page,
  approvalFilter,
  completedFilter,
  providerFilter,
  workTypeFilter,
  pageSize,
  handlePaginationChange,
  handleChangeApprovalFilter,
  handleChangeCompletedFilter,
  handleChangeProviderFilter,
  handleChangeWorkTypeFilter,
  deleteCShift,
  approveHoursCShift
}) => {
  const { count = 0, results = [] } = cShiftRequestSuccess;
  const approvedOptions = [
    { text: "Approved", value: true },
    { text: "Rejected", value: false },
    { text: "Pending", value: "" },
    { text: "All", value: null }
  ];
  const completedOptions = [
    { text: "Completed", value: true },
    { text: "Incomplete", value: false },
    { text: "All", value: null }
  ];
  const manageOptions = (user.client.employees || []).map(employee => {
    const name =
      `${employee.provider.first_name} ${employee.provider.last_name}`.trim() ||
      "No Name";
    return {
      text: `${name} <${employee.provider.email}>`,
      value: employee.uuid
    };
  });
  manageOptions.push({ text: `All`, value: null });
  const workTypeOptions = (user.client.work_types || []).map(workType => {
    return {
      text: `${workType.label}`,
      value: workType.uuid,
      label: (
        <Label
          circular
          empty
          style={{
            backgroundColor: workType.color,
            borderColor: workType.color
          }}
        />
      )
    };
  });
  workTypeOptions.push({ text: `All`, value: null });
  const OLD_PEOPLE_TIME_FORMAT = "dddd, MMMM Do YYYY, h:mm a ";
  return (
    <Container>
      <Header>Shifts</Header>
      <Segment.Group horizontal>
        <Button
          attached="left"
          color="green"
          size="big"
          as={Link}
          to="/user/profile/client/add-shift"
        >
          Schedule Shift
        </Button>
        <Segment>
          {"Filter by Provider Approval "}
          <Dropdown
            inline
            placeholder={approvalFilter === null ? `All` : `Pending`}
            options={approvedOptions}
            onChange={handleChangeApprovalFilter}
            value={approvalFilter}
          />
          {" and Completed "}
          <Dropdown
            inline
            placeholder="All"
            options={completedOptions}
            onChange={handleChangeCompletedFilter}
            value={completedFilter}
          />
          {" and Provider "}
          <Dropdown
            inline
            placeholder="All"
            options={manageOptions}
            onChange={handleChangeProviderFilter}
            value={providerFilter}
          />
          {" and Work Type "}
          <Dropdown
            inline
            placeholder="All"
            options={workTypeOptions}
            onChange={handleChangeWorkTypeFilter}
            value={workTypeFilter}
          />
        </Segment>
      </Segment.Group>
      {!!isSendingCShiftRequest && <Loader content="Loading" active />}
      {!isSendingCShiftRequest &&
        results.length > 0 && (
          <Item.Group divided>
            {results.map(result => {
              const employee = getEmployeeFromPrice(result.price, user) || {};
              const provider = employee.provider || {};
              const price = getPriceFromPrice(result.price, user) || {};
              const workType = price.work_type;
              const checkedIn =
                !!result.actual_start && utc(result.actual_start, ISO_8601);
              const checkedOut =
                !!result.actual_end && utc(result.actual_end, ISO_8601);
              const min = duration(
                utc(result.set_end, ISO_8601) - utc(result.set_start, ISO_8601),
                "milliseconds"
              ).as("minutes");
              let displayDuration = duration(min, "minutes").humanize();
              if (min % 60) {
                displayDuration = duration(
                  Math.floor(min / 60),
                  "hours"
                ).humanize();
                displayDuration += ` and ${duration(
                  min % 60,
                  "minutes"
                ).humanize()}`;
              }

              return (
                <Item key={result.uuid} style={{ justifyContent: "space-between" }}>
                  <Item.Content style={{ minWidth: "14em", paddingRight: "1em" }}>
                    <Item.Header>
                      <Label
                        circular
                        empty
                        style={{
                          backgroundColor: workType.color,
                          borderColor: workType.color
                        }}
                      />
                      {workType.label}
                    </Item.Header>
                    <Item.Extra>
                      <ShiftLabel
                        provider_approved={result.provider_approved}
                        client_approved_start={result.approved_start}
                        client_approved_end={result.approved_end}
                      />
                    </Item.Extra>
                    <Item.Meta>
                      {"Scheduled for " +
                        utc(result.set_start, ISO_8601)
                          .local(false)
                          .format(OLD_PEOPLE_TIME_FORMAT)}
                    </Item.Meta>
                    <Item.Meta>{displayDuration}</Item.Meta>
                    <Item.Meta>{`Rate $${price.amount}/hour`}</Item.Meta>
                    {/* <Item.Description>{result.description}</Item.Description> */}
                    {/* <code>{JSON.stringify(result, null, 2)}</code> */}
                    <Item.Description>
                      {`${provider.first_name} ${provider.last_name}`.trim() ||
                        "No Name!"}{" "}
                      <a href={"mailto:" + provider.email}>{provider.email}</a>
                    </Item.Description>
                  </Item.Content>
                  {!checkedIn && (
                    <Item.Extra>
                      <Popup
                        content={
                          <div>
                            Are you sure you want to delete this shift?<br />
                            <Button
                              basic
                              color="red"
                              size="small"
                              onClick={() => deleteCShift(result.uuid)}
                            >
                              Confirm Deletion
                            </Button>
                          </div>
                        }
                        trigger={
                          <Button color="red" floated="right">
                            Delete
                          </Button>
                        }
                        on="click"
                        position="top right"
                      />
                      <Button
                        primary
                        floated="right"
                        as={Link}
                        to={`/user/profile/client/edit-shift/${result.uuid}`}
                      >
                        Edit
                      </Button>
                    </Item.Extra>
                  )}
                  {checkedIn && (
                    <Fragment>
                      <Item.Content style={{ flex: "2 0 auto" }}>
                        <Item.Description>
                          {result.description && (
                            <Message>{result.description}</Message>
                          )}
                          {result.approved_start && (
                            <Fragment>
                              <strong>Client</strong>
                              <List bulleted>
                                <List.Item>
                                  {`Approved time start ${utc(
                                    result.approved_start
                                  )
                                    .local(false)
                                    .format(OLD_PEOPLE_TIME_FORMAT)}`}
                                </List.Item>
                                <List.Item>{`Approved time end ${utc(
                                  result.approved_end
                                )
                                  .local(false)
                                  .format(OLD_PEOPLE_TIME_FORMAT)}`}</List.Item>
                              </List>
                            </Fragment>
                          )}
                          <strong>Provider</strong>
                          <List bulleted>
                            <List.Item>
                              {"Checked in at " +
                                checkedIn
                                  .local(false)
                                  .format(OLD_PEOPLE_TIME_FORMAT)}
                            </List.Item>
                            {checkedOut && (
                              <List.Item>
                                {"Checked out at " +
                                  checkedOut
                                    .local(false)
                                    .format(OLD_PEOPLE_TIME_FORMAT)}
                              </List.Item>
                            )}
                          </List>
                          {result.chart && (
                            <Message>
                              <Message.Header>Chart</Message.Header>
                              {result.chart}
                            </Message>
                          )}
                        </Item.Description>
                      </Item.Content>
                      <Item.Extra style={{ flex: "1 1 auto" }}>
                        <Popup
                          content={
                            <div>
                              Are you sure you want to delete this shift?<br />
                              <Button
                                basic
                                color="red"
                                size="small"
                                onClick={() => deleteCShift(result.uuid)}
                              >
                                Confirm Deletion
                              </Button>
                            </div>
                          }
                          trigger={
                            <Button color="red" floated="right">
                              Delete
                            </Button>
                          }
                          on="click"
                          position="top right"
                        />
                        <Button
                          primary
                          floated="right"
                          as={Link}
                          to={`/user/profile/client/edit-shift/${result.uuid}`}
                        >
                          Adjust Hours
                        </Button>
                        {!result.approved_start && (
                          <Button
                            color="green"
                            floated="right"
                            onClick={() => approveHoursCShift(result)}
                          >
                            Approve Hours
                          </Button>
                        )}
                      </Item.Extra>
                    </Fragment>
                  )}
                </Item>
              );
            })}
          </Item.Group>
        )}
      <div style={{ textAlign: "center" }}>
        <Pagination
          activePage={page}
          onPageChange={handlePaginationChange}
          totalPages={Math.ceil(count / pageSize)}
          boundaryRange={1}
          siblingRange={1}
          size="mini"
          firstItem={undefined}
          lastItem={undefined}
          prevItem={null}
          nextItem={null}
        />
      </div>
    </Container>
  );
};

export default connect(mapStateToProps)(ClientShifts);
