import React, { Component } from 'react';
import { withRouter } from 'react-router';
import { Link } from 'react-router-dom';
import moment from 'moment';
import _ from 'lodash';
import FontAwesome from 'react-fontawesome';
import Textarea from 'react-textarea-autosize';
import { connect } from 'react-redux';
import { jobsLoaded, jobStatusesUpdate } from '../actions';
import Config, { PlussCore } from '../feature.config';
import { maintenanceActions, reactionActions } from '../apis';
import { STATUS_NOT_ACTIONED, jobPriorityOptions, getJobPriority } from '../helper';
import { values } from '../values.config';

const { Apis, Helper, Session, Colours, Components } = PlussCore;
const IMAGE_SIZE_NOTE = 72;

class Job extends Component {
  constructor(props) {
    super(props);
    this.state = {
      jobId: Helper.safeReadParams(props, 'jobId') ? props.match.params.jobId : null,
      job: null,
      showingSelector: false,
      updating: false,
      comments: [],
      commentInput: '',
      loadingComments: false,
      priorityChangerOpen: false,
      statusChangerOpen: false,
      addNoteOpen: false,
      noteAttachments: [],
      noteInput: '',
      noteImages: [],
      assignees: [],
    };
  }

  UNSAFE_componentWillReceiveProps(nextProps) {
    Session.checkLoggedIn(this, this.props.auth);
  }

  componentDidMount() {
    this.props.jobStatusesUpdate(this.props.auth.site);
    if (this.state.jobId) {
      this.getJob();
      this.getComments();
      this.getAssignees();
    }
  }

  getJob = async () => {
    try {
      const res = await maintenanceActions.getJob(this.props.auth.site, this.state.jobId);
      this.setState({ updating: false });
      res.data.location = res.data.site;
      this.setJob(res.data);
    } catch (error) {
      console.error('getJob', error);
    }
  };

  getAssignees = async () => {
    try {
      const res = await maintenanceActions.getAssignees(this.props.auth.site);
      this.setState({ assignees: res.data.Users });
    } catch (error) {
      console.error('getAssignees', error);
    }
  };

  getStatusType = (status) => {
    const { statusTypes } = this.props;
    let statusType = statusTypes.find((s) => s.text === status);
    if (!statusType) {
      const defaultStatus = statusTypes.find((s) => s.category === STATUS_NOT_ACTIONED);
      statusType = { ...defaultStatus, text: status };
    }
    return statusType;
  };

  setJob = (job) => {
    if (_.isEmpty(job.lastActivity)) {
      job.lastActivity = '-- --';
      job.noActivity = true;
    }
    if (_.isEmpty(job.status)) {
      job.status = 'Unassigned';
      job.notStatus = true;
    }
    if (_.isEmpty(job.audience)) {
      job.audience = [{ displayName: 'Unassigned', isEmpty: true }];
    }
    let needToMarkSeen = false;
    if (!job.seen) {
      job.seen = true;
      needToMarkSeen = true;
    }
    this.setState({ job }, () => {
      if (needToMarkSeen) this.markSeen();
    });
    this.props.jobsLoaded([job]);
  };

  editJob = () => {};

  isReadyToSaveNote = () => {
    const { noteAttachments, noteInput, noteImages } = this.state;
    if (_.some(noteAttachments, (n) => n.Uploading)) return false;
    return !_.isEmpty(noteInput) || !_.isEmpty(noteAttachments) || !_.isEmpty(noteImages);
  };

  onOpenAddNote = () => {
    this.setState({ addNoteOpen: true, editingNote: null });
  };

  onCloseAddNote = () => {
    const newState = { addNoteOpen: false, editingNote: null };
    if (!!this.state.editingNote) {
      newState.noteInput = '';
      newState.noteAttachments = [];
      newState.noteImages = [];
    }
    this.setState(newState);
  };

  onOpenNoteMenu = (index) => {
    if (this.state.noteMenuOpen === index) {
      this.setState({ noteMenuOpen: null });
    } else {
      this.setState({ noteMenuOpen: index });
    }
  };

  onHandlePDFFileChange = (event) => {
    const file = event.target.files[0];
    if (!file || this.state.uploadingNoteAttachment) return;
    const noteAttachments = [...this.state.noteAttachments];
    const newAttachment = {
      Uploading: true,
      Title: file.name,
    };
    noteAttachments.push(newAttachment);
    this.setState({
      noteAttachments,
    });
    Apis.fileActions
      .uploadMediaAsync(file, file.name)
      .then((fileRes) => {
        newAttachment.Source = fileRes;
        newAttachment.Uploading = false;
        this.setState({
          noteAttachments: [...this.state.noteAttachments],
        });
      })
      .catch((uploadErrorRes) => {
        console.log(uploadErrorRes);
        newAttachment.Uploading = false;
        this.setState({
          noteAttachments: [...this.state.noteAttachments],
        });
      });
    event.target.value = '';
  };

  onRemoveAttachment = (a) => {
    const index = this.state.noteAttachments.indexOf(a);
    if (index > -1) {
      const newAttachments = [...this.state.noteAttachments];
      newAttachments.splice(index, 1);
      this.setState({
        noteAttachments: newAttachments,
      });
    }
  };

  onShowSelectAssignee = () => {
    this.setState({
      showingAssigneeSelector: true,
    });
  };

  onCloseSelectAssignee = () => {
    this.setState({
      showingAssigneeSelector: false,
    });
  };

  onSelectAssignee = (user) => {
    this.setState({
      selectedAssignee: user,
    });
  };

  onConfirmAssignee = async () => {
    this.setState({
      confirmingAssignee: true,
    });
    try {
      if (this.state.selectedAssignee) {
        await this.onAssignUser(this.state.selectedAssignee.id);
      }
      this.onCloseSelectAssignee();
    } catch (error) {
      console.error('onConfirmAssignee', error);
    }
    this.setState({
      confirmingAssignee: false,
    });
  };

  // Method to handle user assignment
  onAssignUser = async (userId) => {
    try {
      const res = await maintenanceActions.assignJob(this.state.jobId, userId);
      this.getJob();
    } catch (err) {
      console.error('onAssignUser', err);
    }
  };

  onConfirmAddNote = async () => {
    if (!this.isReadyToSaveNote()) return;

    try {
      this.setState({ submittingNote: true });
      const res = await (this.state.editingNote
        ? maintenanceActions.editNote(
            this.state.jobId,
            this.state.editingNote,
            this.state.noteInput,
            this.state.noteAttachments.map((a) => {
              return {
                Title: a.Title,
                Source: a.Source,
              };
            }),
            this.state.noteImages,
          )
        : maintenanceActions.addNote(
            this.state.jobId,
            this.state.noteInput,
            this.state.noteAttachments.map((a) => {
              return {
                Title: a.Title,
                Source: a.Source,
              };
            }),
            this.state.noteImages,
          ));
      this.setState(
        {
          job: res.data.job,
          submittingNote: false,
          addNoteOpen: false,
          noteInput: '',
          noteAttachments: [],
          noteImages: [],
          editingNote: null,
        },
        () => {
          this.props.jobsLoaded([this.state.job]);
        },
      );
    } catch (err) {
      console.error('onConfirmAddNote', err);
    }
  };

  onDeleteNote = (n) => {
    if (!window.confirm(values.textAreYouSureYouWantToDeleteNote)) {
      this.setState({ noteMenuOpen: null });
      return;
    }

    maintenanceActions.deleteNote(this.state.jobId, n.Id);
    const newNotes = _.filter(this.state.job.Notes, (note) => note.Id !== n.Id);
    const newJob = { ...this.state.job };
    newJob.Notes = newNotes;
    this.setState({ job: newJob, noteMenuOpen: null });
  };

  onOpenEditNote = (n) => {
    this.setState(
      {
        noteAttachments: n.Attachments || [],
        noteImages: n.Images || [],
        noteInput: n.Note || '',
        addNoteOpen: true,
        editingNote: n.Id,
        noteMenuOpen: null,
      },
      this.checkSetImage,
    );
  };

  markSeen = () => {
    const { job } = this.state;
    const { auth } = this.props;
    // Must have maintenance permission and not the requester
    if (!Session.validateAccess(auth.site, values.permissionMaintenanceTracking, auth)) return;
    if (auth.user.Id === job.userID) return;

    this.setState({ updating: true }, async () => {
      try {
        const update = {
          id: job.id,
          seen: true,
          status: job.status || 'Unassigned',
        };

        await maintenanceActions.editJob(update, auth.site);
      } catch (error) {
        this.setState({ updating: false });
        console.log('markSeen error', error);
        alert('Something went wrong with the request. Please try again.');
      }
    });
  };

  getComments = () => {
    reactionActions.getComments(this.state.jobId, values.commentKey, 0).then((res) => {
      this.setState({ comments: res.data });
    });
  };

  checkSetImage() {
    if (this.imageInput && !_.isEmpty(this.state.noteImages)) {
      this.imageInput.getWrappedInstance().setValue(this.state.noteImages);
    } else {
      setTimeout(this.checkSetImage, 100);
    }
  }

  onAddComment = async () => {
    const { commentInput, jobId, job, comments } = this.state;
    try {
      this.setState({ commentInput: '' });
      const res = await reactionActions.addComment(jobId, values.commentKey, job.title, job.site, commentInput);
      this.setState({ comments: [...comments, res.data] });
    } catch (error) {
      console.error('onAddComment', error);
    }
  };

  onHandleChange = (event) => {
    var stateChange = {};
    stateChange[event.target.getAttribute('id')] = event.target.value;
    this.setState(stateChange);
  };

  onTogglePriorityChanger = () => {
    this.setState({ priorityChangerOpen: !this.state.priorityChangerOpen });
  };

  onSelectPriority = async (priority) => {
    this.setState({
      job: { ...this.state.job, priority },
      priorityChangerOpen: false,
    });

    try {
      const res = await maintenanceActions.editJobPriority(this.state.job.id, priority);
      const { job } = res.data;
      this.props.jobsLoaded([job]);
      this.setState({ job });
    } catch (error) {
      console.error('onSelectPriority', error);
    }
  };

  onToggleStatusChanger = () => {
    this.setState({ statusChangerOpen: !this.state.statusChangerOpen });
  };

  onSelectStatus = async (status) => {
    this.setState({
      job: {
        ...this.state.job,
        status: status,
      },
      statusChangerOpen: false,
    });

    try {
      const res = await maintenanceActions.editJobStatus(this.state.job.id, status);
      const { job } = res.data;
      this.props.jobsLoaded([job]);
      this.setState({ job });
    } catch (error) {
      console.error('onSelectStatus', error);
    }
  };

  renderPriorityChanger() {
    if (!this.state.priorityChangerOpen) return null;
    return (
      <div className="statusChanger statusChanger-priority">
        {jobPriorityOptions.map((p) => {
          return (
            <div key={p.name} className="statusLabel" onClick={() => this.onSelectPriority(p.name)} style={{ backgroundColor: p.color }}>
              <span className="statusLabel_text">{p.name}</span>
            </div>
          );
        })}
      </div>
    );
  }

  renderPriorityLabel() {
    const { auth } = this.props;
    if (!Session.validateAccess(auth.site, values.permissionMaintenanceTracking, auth)) return null;

    const { job } = this.state;
    if (!job) return null;

    const selectedPriority = getJobPriority(job.priority);
    return (
      <div
        className="statusLabel marginTop-5 pointer"
        onClick={this.onTogglePriorityChanger}
        style={{ backgroundColor: selectedPriority.color }}
      >
        <span className="statusLabel_text">{job.priority || selectedPriority.name}</span>
        {this.renderPriorityChanger()}
      </div>
    );
  }

  renderStatusLabel() {
    if (!this.state.job.status) return null;
    const statusType = this.getStatusType(this.state.job.status);
    const { auth } = this.props;
    if (Session.validateAccess(auth.site, values.permissionMaintenanceTracking, auth)) {
      return (
        <div className="statusLabel pointer" onClick={this.onToggleStatusChanger} style={{ backgroundColor: statusType.color }}>
          <span className="statusLabel_text">{statusType.text}</span>
          {this.renderStatusChanger()}
        </div>
      );
    }
    return (
      <div className="statusLabel" style={{ backgroundColor: statusType.color }}>
        <span className="statusLabel_text">{statusType.text}</span>
      </div>
    );
  }

  renderNotesButton() {
    const { auth } = this.props;
    if (!Session.validateAccess(auth.site, values.permissionMaintenanceTracking, auth)) return null;
    return (
      <div
        className="statusLabel pointer"
        onClick={this.onOpenAddNote}
        style={{ backgroundColor: Config.env.colourBrandingMain, marginLeft: 8 }}
      >
        <span className="statusLabel_text">Add Note</span>
      </div>
    );
  }

  renderAssignButton() {
    const { auth } = this.props;
    if (!Session.validateAccess(auth.site, values.permissionMaintenanceTracking, auth)) return null;
    return (
      <div
        className="statusLabel pointer"
        onClick={this.onShowSelectAssignee}
        style={{ backgroundColor: Config.env.colourBrandingMain, marginLeft: 8 }}
      >
        <span className="statusLabel_text">Assign</span>
      </div>
    );
  }

  renderStatusChanger() {
    if (!this.state.statusChangerOpen) return null;
    const { statusTypes } = this.props;

    return (
      <div className="statusChanger statusChanger-maintenance">
        {statusTypes.map((status) => {
          return (
            <div
              key={status.text}
              className="statusLabel"
              onClick={() => this.onSelectStatus(status.text)}
              style={{ backgroundColor: status.color }}
            >
              <span className="statusLabel_text">{status.text}</span>
            </div>
          );
        })}
      </div>
    );
  }

  renderComment(c) {
    return <Components.Comment key={c.Id} comment={c} />;
    return (
      <div key={c.Id} className="comment">
        <p className="comment_text">{Helper.toParagraphed(c.Comment)}</p>
        <div className="comment_bottom">
          <Components.ProfilePic className="comment_profilePic" size={25} image={c.User.profilePic} />
          <p className="comment_name">{c.User.displayName}</p>
          <p className="comment_time">{moment.utc(c.Timestamp).local().format('D MMM YYYY • h:mma')}</p>
        </div>
      </div>
    );
  }

  renderCommentSection() {
    if (this.state.loadingComments) return null;

    return (
      <div className="padding-60 paddingLeft-20">
        <div className="newTopBar paddingLeft-40">
          <Components.Text type="formTitleSmall" className="marginBottom-16">
            Comments
          </Components.Text>
          <div className="commentSection">{this.state.comments.map((c) => this.renderComment(c))}</div>
          <div className="commentReply">
            <div
              className={`commentReply_button${!_.isEmpty(this.state.commentInput) ? ' commentReply_button-active' : ''}`}
              onClick={this.onAddComment}
            >
              <FontAwesome className="commentReply_icon" name="paper-plane-o" />
            </div>
            <Textarea
              id="commentInput"
              placeholder="Reply here..."
              type="text"
              className="commentReply_input"
              value={this.state.commentInput}
              onChange={(e) => this.onHandleChange(e)}
            />
          </div>
        </div>
      </div>
    );
  }

  renderImageGrid(images, size = undefined) {
    const imagesToUse = images && images.length > 0 ? images : [];
    return (
      <div className="imageGrid">
        {imagesToUse.map((image, i) => {
          return (
            <a href={image} target="_blank" rel="noopener noreferrer" key={i}>
              <div
                className="imageGrid_image"
                style={{ backgroundImage: `url('${Helper.get1400(image)}')`, width: size, height: size }}
              ></div>
            </a>
          );
        })}
      </div>
    );
  }

  renderImages() {
    if (_.isEmpty(this.state.job.image) && _.isEmpty(this.state.job.images)) return null;

    const imagesToUse = _.isEmpty(this.state.job.image) ? this.state.job.images : [this.state.job.image];
    return (
      <div className="padding-60 paddingVertical-40 bottomDivideBorder">
        <Components.Text type="formTitleSmall" className="marginBottom-16">
          Images
        </Components.Text>
        {this.renderImageGrid(imagesToUse)}
      </div>
    );
  }

  renderCustomFields() {
    const { job } = this.state;
    const { customFields } = job;

    const labelClass = 'fieldLabel';
    const answerClass = 'fontRegular fontSize-16 text-dark marginTop-5';

    const renderAnswer = (field) => {
      switch (field.type) {
        case 'date':
          return <div className={answerClass}>{field.answer ? moment(field.answer, 'YYYY-MM-DD').format('DD-MMM-YYYY') : ''}</div>;
        case 'time':
          return <div className={answerClass}>{field.answer ? moment(field.answer, 'HH:mm').format('h:mm a') : ''}</div>;
        case 'yn':
          return <div className={answerClass}>{field.answer ? 'Yes' : 'No'}</div>;
        case 'checkbox':
          return <div className={answerClass}>{field.answer && Array.isArray(field.answer) ? field.answer.join(', ') : ''}</div>;
        case 'image':
          return this.renderImageGrid(field.answer);
        default:
          return <div className={answerClass}>{field.answer}</div>;
      }
    };

    return (
      <div className="padding-60 paddingVertical-40 bottomDivideBorder">
        {customFields.map((field, index) => {
          if (['staticTitle', 'staticText'].includes(field.type)) return null;
          if (_.isNil(field.answer) || field.answer === '') return null;
          return (
            <div key={index} className="marginTop-16">
              <div className={labelClass}>{field.label}</div>
              {renderAnswer(field)}
            </div>
          );
        })}
      </div>
    );
  }

  renderInner() {
    if (this.state.job == null) return null;
    const { customFields } = this.state.job;
    const hasCustomFields = customFields && customFields.length > 0;

    return (
      <div style={{ paddingBottom: 40 }}>
        <div className="padding-60 paddingVertical-40 bottomDivideBorder relative">
          <Components.Text type="formTitleLarge" className="marginBottom-8">
            {this.state.job.title || values.textSingularName}
          </Components.Text>
          <Components.Text type="formTitleMedium" className="marginBottom-24">
            {values.textEntityName} #{this.state.job.jobId}
          </Components.Text>
          <div className="marginTop-16">
            <div className={'fieldLabel'}>Submission date</div>
            <div className={'fontRegular fontSize-16 text-dark marginTop-5'}>
              {moment.utc(this.state.job.createdTime).local().format('D MMM YY')}
            </div>
          </div>
          <div className="marginTop-16">
            <div className={'fieldLabel'}>Type</div>
            <div className={'fontRegular fontSize-16 text-dark marginTop-5'}>{this.state.job.type}</div>
          </div>
          <div className="marginTop-16">
            <div className={'fieldLabel'}>Address</div>
            <div className={'fontRegular fontSize-16 text-dark marginTop-5'}>{this.state.job.room}</div>
          </div>
          {hasCustomFields ? null : (
            <div className="marginTop-16">
              <div className={'fieldLabel'}>Description {this.state.job.image ? '- (image supplied)' : ''}</div>
              <div className={'fontRegular fontSize-16 text-dark marginTop-5'}>{this.state.job.description}</div>
            </div>
          )}
        </div>
        <div className="padding-60 paddingVertical-40 bottomDivideBorder">
          <Components.Text type="formTitleSmall" className="marginBottom-16">
            Contact Details
          </Components.Text>
          <div className="marginTop-16">
            <div className={'fieldLabel'}>Name</div>
            <div className={'fontRegular fontSize-16 text-dark marginTop-5'}>{this.state.job.userName}</div>
          </div>
          <div className="marginTop-16">
            <div className={'fieldLabel'}>Contact number</div>
            <div className={'fontRegular fontSize-16 text-dark marginTop-5'}>
              {_.isEmpty(this.state.job.phone) ? 'No phone provided' : this.state.job.phone}
            </div>
          </div>
          {hasCustomFields ? null : (
            <div>
              <div className="marginTop-16">
                <div className={'fieldLabel'}>Should person be home?</div>
                <div className={'fontRegular fontSize-16 text-dark marginTop-5'}>{this.state.job.isHome ? 'Yes' : 'No'}</div>
              </div>
              {this.state.job.isHome && this.state.job.homeText && (
                <div className="marginTop-16">
                  <div className={'fieldLabel'}>When</div>
                  <div className={'fontRegular fontSize-16 text-dark marginTop-5'}>{this.state.job.homeText}</div>
                </div>
              )}
            </div>
          )}
        </div>
        {hasCustomFields ? null : this.renderImages()}
        {hasCustomFields ? this.renderCustomFields() : null}
        {this.renderCommentSection()}
      </div>
    );
  }

  renderHistoryEntry(e, i) {
    const { job } = this.state;
    const entryToUse = e || {
      timestamp: job.createdTime,
      status: 'Unassigned',
      user: {
        displayName: job.userName,
        id: job.userID,
        profilePic: job.userProfilePic,
      },
    };
    const statusType = this.getStatusType(entryToUse.status);
    return (
      <div className="ticketHistoryEntry" key={i}>
        <p className="ticketHistoryEntry_timestamp">{moment.utc(entryToUse.timestamp).local().format('D MMM YYYY h:mma')}</p>
        <div className="statusLabel statusLabel-large statusLabel-full" style={{ backgroundColor: statusType.color }}>
          <span className="statusLabel_text">
            {e ? `${entryToUse.user.displayName} marked as ${statusType.text}` : `${values.textEntityName} opened`}
          </span>
        </div>
      </div>
    );
  }

  renderNote(note, index) {
    return (
      <div className="ticketHistoryEntry" key={index}>
        <p className="ticketHistoryEntry_timestamp">{moment.utc(note.Timestamp).local().format('D MMM YYYY h:mma')}</p>
        <div className="statusLabel statusLabel-large statusLabel-full" style={{ backgroundColor: '#6e79c5' }}>
          <span className="statusLabel_text">Staff Notes</span>
        </div>
        <div className="maintenanceNote">
          <div className="maintenanceNote_top">
            {this.props.auth && this.props.auth.user && this.props.auth.user.Id === note.User.id && (
              <Components.SVGIcon
                colour={Colours.COLOUR_DUSK_LIGHT}
                icon="more15"
                className="maintenanceNote_moreIcon"
                onClick={() => this.onOpenNoteMenu(index)}
              />
            )}
            <p className="maintenanceNote_name">{note.User.displayName}</p>
            {this.state.noteMenuOpen === index && (
              <Components.MoreMenu
                options={[
                  {
                    key: 'edit',
                    text: 'Edit',
                    onPress: () => this.onOpenEditNote(note),
                  },
                  {
                    key: 'delete',
                    text: 'Delete',
                    onPress: () => this.onDeleteNote(note),
                  },
                ]}
              />
            )}
          </div>
          <p className="maintenanceNote_text">{Helper.toParagraphed(note.Note)}</p>
          {note.Attachments.map((a, i) => this.renderAttachment(a, i))}
          {note.Images && note.Images.length > 0 ? this.renderImageGrid(note.Images, IMAGE_SIZE_NOTE) : null}
        </div>
      </div>
    );
  }

  renderAssignment() {
    const { job } = this.state;
    if (!job) return null;

    return (
      <div className="padding-32 paddingVertical-40 bottomDivideBorder relative">
        <div className="newTopBar clearfix flex flex-reverse">
          {this.renderAssignButton()}
          <Components.Text type="formTitleSmall" className="flex-1">
            Assignment
          </Components.Text>
        </div>
        <div>
          <div className="marginTop-16">
            <div className={'fieldLabel'}>Assigned to</div>
            <div className={'fontRegular fontSize-16 text-dark marginTop-5'}>
              {job.Assignee ? <Components.UserListing user={job.Assignee} /> : 'Unassigned'}
            </div>
          </div>
        </div>
      </div>
    );
  }

  renderAssignmentEntry(e, i) {
    return (
      <div className="ticketHistoryEntry" key={i}>
        <p className="ticketHistoryEntry_timestamp">{moment.utc(e.timestamp).local().format('D MMM YYYY h:mma')}</p>
        <div className="statusLabel statusLabel-large statusLabel-full" style={{ backgroundColor: Colours.COLOUR_DUSK }}>
          <span className="statusLabel_text">
            {e.user.displayName} assigned the {values.textSingularName} to {e.assignedUser ? e.assignedUser.displayName : 'Unassigned'}
          </span>
        </div>
      </div>
    );
  }

  renderPriority() {
    const { auth } = this.props;
    if (!Session.validateAccess(auth.site, values.permissionMaintenanceTracking, auth)) return null;

    return (
      <div className="padding-32 paddingVertical-40 bottomDivideBorder relative">
        <div className="newTopBar clearfix flex flex-reverse">
          {this.renderPriorityLabel()}
          <Components.Text type="formTitleSmall" className="flex-1">
            Priority
          </Components.Text>
        </div>
      </div>
    );
  }

  renderOverview() {
    const { job } = this.state;
    if (!job || !job.history) return null;

    const source = _.sortBy(
      [
        ...job.history.map((e) => {
          return { ...e, EntryType: e.EntryType || 'status' };
        }),
        ...(job.Notes || []).map((e) => {
          return { ...e, timestamp: e.Timestamp, EntryType: 'note' };
        }),
      ],
      'timestamp',
    );

    return (
      <div className="padding-32 paddingVertical-40 bottomDivideBorder relative">
        <div className="newTopBar clearfix flex flex-reverse">
          {this.renderNotesButton()}
          {this.renderStatusLabel()}
          <Components.Text type="formTitleSmall" className="flex-1">
            Status History
          </Components.Text>
        </div>
        {this.renderHistoryEntry(null, -1)}
        {_.map(source, (e, i) => {
          switch (e.EntryType) {
            case 'status':
              return this.renderHistoryEntry(e, i);
            case 'note':
              return this.renderNote(e, i);
            case 'assignment':
              return this.renderAssignmentEntry(e, i);
            default:
              break;
          }
        })}
      </div>
    );
  }

  renderButtons() {
    return (
      <div>
        <Components.Button
          inline
          buttonType="tertiary"
          onClick={() => {
            window.history.back();
          }}
          isActive
          style={{ marginRight: 16 }}
        >
          Back
        </Components.Button>
        {Session.validateAccess(this.props.auth.site, values.permissionMaintenanceTracking, this.props.auth) &&
          !_.isEmpty(this.state.job) && (
            <Link to={`${values.routeAddRequest}/${this.state.jobId}`}>
              <Components.Button inline style={{ marginRight: 25 }} buttonType="outlined" isActive onClick={this.editJob}>
                Edit Details
              </Components.Button>
            </Link>
          )}
      </div>
    );
  }

  renderAttachment(attachment, index, onRemove) {
    if (!attachment) return null;

    return (
      <Components.Attachment
        key={index}
        uploading={attachment.Uploading}
        source={attachment.Source}
        title={attachment.Title}
        onRemove={onRemove ? () => onRemove(attachment) : undefined}
      />
    );
  }

  renderAddNotePopup() {
    if (!this.state.addNoteOpen) return null;

    if (this.state.submittingNote) {
      return (
        <Components.Popup title="Saving Note" maxWidth={600} hasPadding>
          <div className="flex flex-center-row">
            <FontAwesome className="spinner" name="spinner fa-pulse fa-fw" />
          </div>
        </Components.Popup>
      );
    }

    return (
      <Components.Popup
        title={`${this.state.editingNote ? 'Edit' : 'Add'} Note`}
        onClose={this.onCloseAddNote}
        maxWidth={600}
        hasPadding
        buttons={[
          {
            type: 'primary',
            onClick: this.onConfirmAddNote,
            isActive: this.isReadyToSaveNote(),
            text: 'Save',
          },
          {
            type: 'tertiary',
            onClick: this.onCloseAddNote,
            isActive: true,
            text: 'Cancel',
          },
        ]}
      >
        <Components.GenericInput
          id="noteInput"
          type="textarea"
          componentClass="textarea"
          value={this.state.noteInput}
          placeholder="Enter note"
          onChange={(e) => this.onHandleChange(e)}
          inputStyle={{
            width: 400,
          }}
        />
        <Components.Text type="h5">Attachments</Components.Text>
        {this.state.noteAttachments.map((a, i) => this.renderAttachment(a, i, this.onRemoveAttachment))}
        <input
          ref={(input) => (this.attachmentInput = input)}
          id="attachmentInput"
          type="file"
          className="fileInput"
          onChange={(e) => this.onHandlePDFFileChange(e)}
          accept="application/pdf"
        />
        <div
          className="iconTextButton marginBottom-16"
          onClick={() => {
            this.attachmentInput.click();
          }}
        >
          <FontAwesome className="iconTextButton_icon" name="paperclip" />
          <p className="iconTextButton_text">Add Attachment</p>
        </div>
        <Components.ImageInput
          ref={(ref) => {
            this.imageInput = ref;
          }}
          multiple
          refreshCallback={(images) => {
            this.setState({ noteImages: images });
          }}
        />
      </Components.Popup>
    );
  }

  renderUsers() {
    let content = null;
    if (this.state.confirmingAssignee) {
      content = (
        <div className="flex flex-center-row">
          <FontAwesome className="spinner" name="spinner fa-pulse fa-fw" />
        </div>
      );
    } else if (this.state.selectedAssignee) {
      content = (
        <div>
          <Components.UserListing
            key={this.state.selectedAssignee.id}
            user={this.state.selectedAssignee}
            rightContent={
              <Components.SVGIcon
                className="removeIcon"
                icon="close"
                onClick={() => {
                  this.onSelectAssignee();
                }}
                colour={Colours.COLOUR_DUSK}
              />
            }
          />
        </div>
      );
    } else {
      content = (
        <div>
          <Components.GenericInput
            id="userSearch"
            type="text"
            // label="Search"
            placeholder="Search name"
            value={this.state.userSearch}
            onChange={(e) => this.onHandleChange(e)}
            alwaysShowLabel
          />
          {_.sortBy(this.state.assignees, (u) => u.displayName.toUpperCase())
            .filter((u) => {
              if (_.isEmpty(this.state.userSearch)) return true;
              return u.displayName.toUpperCase().indexOf(this.state.userSearch.toUpperCase()) > -1;
            })
            .map((user) => {
              return (
                <Components.UserListing
                  key={user.id}
                  user={user}
                  onClick={() => {
                    this.onSelectAssignee(user);
                  }}
                />
              );
            })}
        </div>
      );
    }
    return (
      <div className="genericInputContainer">
        <Components.Text type="formLabel">Select User</Components.Text>
        {content}
      </div>
    );
  }

  renderUserSelectionPopup() {
    if (!this.state.showingAssigneeSelector) return null;
    return (
      <Components.Popup
        title="Assign Job"
        onClose={this.onCloseSelectAssignee}
        maxWidth={600}
        hasPadding
        buttons={[
          {
            type: 'primary',
            onClick: this.onConfirmAssignee,
            isActive: !!this.state.selectedAssignee,
            text: 'Confirm',
          },
          {
            type: 'tertiary',
            onClick: this.onCloseSelectAssignee,
            isActive: true,
            text: 'Cancel',
          },
        ]}
      >
        {this.renderUsers()}
      </Components.Popup>
    );
  }

  render() {
    return (
      <Components.OverlayPage>
        {this.renderAddNotePopup()}
        {this.renderUserSelectionPopup()}
        <Components.OverlayPageContents>
          <Components.OverlayPageSection className="pageSectionWrapper--fixedPopupSize">{this.renderInner()}</Components.OverlayPageSection>
          <Components.OverlayPageSection className="pageSectionWrapper--newPopupSide pageSectionWrapper--newPopupSide-fixedWidth">
            {this.renderAssignment()}
            {this.renderPriority()}
            {this.renderOverview()}
          </Components.OverlayPageSection>
        </Components.OverlayPageContents>
        <Components.OverlayPageBottomButtons>{this.renderButtons()}</Components.OverlayPageBottomButtons>
      </Components.OverlayPage>
    );
  }
}

const mapStateToProps = (state) => {
  const { auth } = state;
  return { auth, statusTypes: state[values.reducerKey].jobstatuses };
};

export default connect(mapStateToProps, { jobsLoaded, jobStatusesUpdate })(withRouter(Job));
