import { utc, ISO_8601, duration } from "moment";
import React, { Component } from "react";
import { connect } from "react-redux";
import { Redirect, Link } from "react-router-dom";
import {
  Button,
  Container,
  Dropdown,
  Header,
  Item,
  Segment,
  Pagination,
  Loader,
  Label
} from "semantic-ui-react";
import {
  getEmployerFromPrice,
  getPriceFromPrice
} from "./ProviderShiftsShared";
import {
  setPShiftPage,
  setPShiftApprovalFilter,
  setPShiftCompletedFilter,
  setPShiftClientFilter,
  setPShiftWorkTypeFilter
} from "../../../actions/pShift/reducer.actions";
import {
  getPShiftsRequest,
  updatePShiftRequest
} from "../../../actions/pShift/saga.actions";

class ProviderShifts 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(
      getPShiftsRequest({
        page: this.props.page,
        approved: this.props.approvalFilter,
        completed: this.props.completedFilter,
        manage: this.props.clientFilter,
        work_type: this.props.workTypeFilter,
        page_size: this.state.pageSize
      })
    );
  };

  handlePaginationChange = (event, { activePage }) => {
    this.props.dispatch(
      getPShiftsRequest({
        page: activePage,
        approved: this.props.approvalFilter,
        completed: this.props.completedFilter,
        manage: this.props.clientFilter,
        work_type: this.props.workTypeFilter,
        page_size: this.state.pageSize
      })
    );
    this.props.dispatch(setPShiftPage(activePage));
  };

  handleChangeApprovalFilter = (event, { value }) => {
    this.props.dispatch(
      getPShiftsRequest({
        page: 1,
        approved: value,
        completed: this.props.completedFilter,
        manage: this.props.clientFilter,
        work_type: this.props.workTypeFilter,
        page_size: this.state.pageSize
      })
    );
    this.props.dispatch(setPShiftApprovalFilter(value));
    this.props.dispatch(setPShiftPage(1));
  };

  handleChangeCompletedFilter = (event, { value }) => {
    this.props.dispatch(
      getPShiftsRequest({
        page: 1,
        approved: this.props.approvalFilter,
        completed: value,
        manage: this.props.clientFilter,
        work_type: this.props.workTypeFilter,
        page_size: this.state.pageSize
      })
    );
    this.props.dispatch(setPShiftCompletedFilter(value));
    this.props.dispatch(setPShiftPage(1));
  };

  handleChangeClientFilter = (event, { value }) => {
    this.props.dispatch(
      getPShiftsRequest({
        page: 1,
        approved: this.props.approvalFilter,
        completed: this.props.completedFilter,
        manage: value,
        work_type: this.props.workTypeFilter,
        page_size: this.state.pageSize
      })
    );
    this.props.dispatch(setPShiftClientFilter(value));
    this.props.dispatch(setPShiftPage(1));
  };

  handleChangeWorkTypeFilter = (event, { value }) => {
    this.props.dispatch(
      getPShiftsRequest({
        page: 1,
        approved: this.props.approvalFilter,
        completed: this.props.completedFilter,
        manage: this.props.clientFilter,
        work_type: value,
        page_size: this.state.pageSize
      })
    );
    this.props.dispatch(setPShiftWorkTypeFilter(value));
    this.props.dispatch(setPShiftPage(1));
  };

  handleChangePShiftApproval = (uuid, approved) => {
    return () => {
      this.props.dispatch(
        updatePShiftRequest({ uuid, approved, action: "", chart: null })
      );
    };
  };

  render() {
    const {
      isSendingPShiftRequest,
      pShiftRequestSuccess,
      selfUser,
      page,
      approvalFilter,
      completedFilter,
      clientFilter,
      workTypeFilter
    } = this.props;
    const { pageSize } = this.state;
    if (selfUser.provider) {
      return (
        <ProviderShiftsView
          isSendingPShiftRequest={isSendingPShiftRequest}
          pShiftRequestSuccess={pShiftRequestSuccess}
          page={page}
          approvalFilter={approvalFilter}
          completedFilter={completedFilter}
          clientFilter={clientFilter}
          workTypeFilter={workTypeFilter}
          pageSize={pageSize}
          user={selfUser}
          handlePaginationChange={this.handlePaginationChange}
          handleChangeApprovalFilter={this.handleChangeApprovalFilter}
          handleChangeCompletedFilter={this.handleChangeCompletedFilter}
          handleChangeClientFilter={this.handleChangeClientFilter}
          handleChangeWorkTypeFilter={this.handleChangeWorkTypeFilter}
          handleChangePShiftApproval={this.handleChangePShiftApproval}
        />
      );
    } else {
      return <Redirect to="/" />;
    }
  }
}

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

const ProviderShiftsView = ({
  isSendingPShiftRequest,
  pShiftRequestSuccess,
  user,
  page,
  approvalFilter,
  completedFilter,
  clientFilter,
  workTypeFilter,
  pageSize,
  handlePaginationChange,
  handleChangeApprovalFilter,
  handleChangeCompletedFilter,
  handleChangeClientFilter,
  handleChangeWorkTypeFilter,
  handleChangePShiftApproval
}) => {
  const OLD_PEOPLE_TIME_FORMAT = "dddd, MMMM Do YYYY, h:mm a";
  const { count = 0, results = [] } = pShiftRequestSuccess;
  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.provider.employers || []).map(employer => {
    const name =
      `${employer.client.first_name} ${employer.client.last_name}`.trim() ||
      "No Name";
    return {
      text: `${name} <${employer.client.email}>`,
      value: employer.uuid
    };
  });
  manageOptions.push({ text: `All`, value: null });
  const workTypeMultiOptions = [];
  (user.provider.employers || []).forEach(employer => {
    (employer.prices || []).forEach(price => {
      workTypeMultiOptions.push({
        value: price.work_type.uuid,
        text: price.work_type.label,
        label: (
          <Label
            circular
            empty
            style={{
              backgroundColor: price.work_type.color,
              borderColor: price.work_type.color
            }}
          />
        )
      });
    });
  });
  workTypeMultiOptions.push({ text: `All`, value: null });
  // dedup
  const seen = new Set();
  const workTypeOptions = workTypeMultiOptions.filter(option => {
    return seen.has(option.value) ? false : seen.add(option.value);
  });
  return (
    <Container>
      <Header>Shifts</Header>
      <Segment.Group horizontal>
        <Segment>
          {"Filter by 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 Client "}
          <Dropdown
            inline
            placeholder="All"
            options={manageOptions}
            onChange={handleChangeClientFilter}
            value={clientFilter}
          />
          {" and Work Type "}
          <Dropdown
            inline
            placeholder="All"
            options={workTypeOptions}
            onChange={handleChangeWorkTypeFilter}
            value={workTypeFilter}
          />
        </Segment>
      </Segment.Group>
      {!!isSendingPShiftRequest && <Loader content="Loading" active />}
      {!isSendingPShiftRequest &&
        results.length > 0 && (
          <Item.Group divided>
            {results.map(result => {
              const employer = getEmployerFromPrice(result.price, user) || {};
              const client = employer.client || {};
              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()}`;
              }
              const approved = !!result.approved;
              const rejected = !result.approved && result.approved !== null;
              const pending = result.approved === null;
              return (
                <Item key={result.uuid}>
                  <Item.Content>
                    <Item.Header>
                      <Label
                        circular
                        empty
                        style={{
                          backgroundColor: workType.color,
                          borderColor: workType.color
                        }}
                      />
                      {workType.label}
                    </Item.Header>
                    <Item.Extra>
                      <Label
                        color={approved ? "green" : rejected ? "red" : "grey"}
                        tag
                        size="small"
                      >
                        {approved && "Approved"}
                        {pending && "Approval Pending"}
                        {rejected && "Rejected"}
                      </Label>
                    </Item.Extra>
                    <Item.Meta>
                      {"At " +
                        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>
                      {`${client.first_name} ${client.last_name}`.trim() ||
                        "No Name!"}{" "}
                      <a href={"mailto:" + client.email}>{client.email}</a>
                    </Item.Description>
                    {checkedIn && (
                      <Item.Meta>
                        {"Checked in at: " +
                          checkedIn.local(false).format(OLD_PEOPLE_TIME_FORMAT)}
                      </Item.Meta>
                    )}
                    {checkedOut && (
                      <Item.Meta>
                        {"Checked out at: " +
                          checkedOut
                            .local(false)
                            .format(OLD_PEOPLE_TIME_FORMAT)}
                      </Item.Meta>
                    )}
                  </Item.Content>
                  <Item.Extra>
                    {!checkedIn && (
                      <Button.Group floated="right">
                        {!approved && (
                          <Button
                            color="green"
                            onClick={handleChangePShiftApproval(
                              result.uuid,
                              true
                            )}
                          >
                            Approve
                          </Button>
                        )}
                        {!rejected && (
                          <Button
                            color="red"
                            onClick={handleChangePShiftApproval(
                              result.uuid,
                              false
                            )}
                          >
                            Reject
                          </Button>
                        )}
                      </Button.Group>
                    )}
                    <Button
                      floated="right"
                      as={Link}
                      to={`/user/profile/provider/shifts/${result.uuid}`}
                    >
                      Details{approved && !checkedIn && " & Check In"}
                      {approved && checkedIn && !checkedOut && " & Check Out"}
                    </Button>
                  </Item.Extra>
                </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)(ProviderShifts);
