import React, { FunctionComponent } from "react";
import { formatDate } from "../util/date";
import { Event } from "../types/event";
import { Link } from "react-router-dom";
import { WorkgroupLink } from "./WorkgroupLink";
import { DecisioSupportFileLink } from "./DecisionSupportFileLink";

export interface TimelineProps {
  events?: Event[]
}

export const Timeline: FunctionComponent<TimelineProps> = ({ events }) => {
  events = debounceEvents(events) || [];
  return (
    <React.Fragment>
      <div className="timeline" style={{width: '100%'}}>
        {
          events.map(evt => {
            return (
              <div key={evt.id} className="timeline-item">
                {renderEventMarker(evt)}
                <div className="timeline-content">
                  <p className="heading">{formatDate(evt.createdAt)}</p>
                  {renderEventContent(evt)}
                </div>
              </div>
            );
          })
        }
        {
          events.length === 0 ?
          <p className="has-text-centered is-italic mb-1 mt-1">Aucun évènement.</p> :
          null
        }
      </div>
    </React.Fragment>
  );
}

function debounceEvents(events: Event[]): Event[] {
  const debounced = [];
  for(let evt: Event, i = 0; (evt = events[i]); ++i) {
    const prev = i > 0 ? events[i-1] : null;
    
    if (!prev) {
      debounced.push(evt);
      continue;
    }

    const isSame = evt.objectId === prev.objectId && 
      evt.objectType === prev.objectType &&
      evt.type === prev.type &&
      evt.user.id === prev.user.id
    ;

    if (isSame) continue;

    debounced.push(evt);
  }

  return debounced;
}

const eventMarkerMap = {
  "closed": (evt:Event) => (
    <div className="timeline-marker is-icon is-danger">
      <i className="fa fa-times"></i>
    </div>
  ),
  "created": (evt:Event) => (
    <div className="timeline-marker is-icon is-success">
      <i className="fa fa-plus"></i>
    </div>
  ),
  "updated": (evt:Event) => (
    <div className="timeline-marker is-icon is-info">
      <i className="fa fa-pen"></i>
    </div>
  ),
  "title-changed": (evt:Event) => (
    <div className="timeline-marker is-icon is-info">
      <i className="fa fa-pen"></i>
    </div>
  ),
  "status-changed": (evt:Event) => (
    <div className="timeline-marker is-icon is-primary">
      <i className="fa fa-star"></i>
    </div>
  ),
  "joined": (evt:Event) => (
    <div className="timeline-marker is-icon is-info">
      <i className="fa fa-users"></i>
    </div>
  ),
  "leaved": (evt:Event) => (
    <div className="timeline-marker is-icon is-warning">
      <i className="fas fa-users-slash"></i>
    </div>
  ),
}

function renderEventMarker(evt: Event) {
  const render = eventMarkerMap[evt.type];
  if (!render) return ( <div className="timeline-marker"></div> );
  return render(evt);
}

const eventContentMap = {
  "created": {
    "workgroup": (evt:Event) => {
      return (
        <React.Fragment>
          <span>{`${evt.user.name ? evt.user.name : evt.user.email} a créé le groupe de travail `}</span>
          "<WorkgroupLink workgroupId={evt.objectId} />".
        </React.Fragment> 
      );
    },
    "dsf": (evt:Event) => {
      return (
        <React.Fragment>
          <span>{`${evt.user.name ? evt.user.name : evt.user.email} a créé le dossier d'aide à la décision `}</span>
          "<DecisioSupportFileLink decisionSupportFileId={evt.objectId} />".
        </React.Fragment> 
      );
    },
  },
  "title-changed": {
    "dsf": (evt:Event) => {
      return (
        <React.Fragment>
          <span>{`${evt.user.name ? evt.user.name : evt.user.email} a modifié le titre du dossier d'aide à la décision `}</span>
          "<DecisioSupportFileLink decisionSupportFileId={evt.objectId} />".
        </React.Fragment>
      )
    }
  },
  "status-changed": {
    "dsf": (evt:Event) => {
      return (
        <React.Fragment>
          <span>{`${evt.user.name ? evt.user.name : evt.user.email} a modifié le statut du dossier d'aide à la décision `}</span>
          "<DecisioSupportFileLink decisionSupportFileId={evt.objectId} />".
        </React.Fragment>
      )
    }
  },
  "joined": {
    "workgroup": (evt:Event) => {
      return (
        <React.Fragment>
          <span>{`${evt.user.name ? evt.user.name : evt.user.email} a rejoint le groupe de travail `}</span>
          "<WorkgroupLink workgroupId={evt.objectId} />".
        </React.Fragment> 
      );
    },
  },
  "updated": {
    "workgroup": (evt:Event) => {
      return (
        <React.Fragment>
          <span>{`${evt.user.name ? evt.user.name : evt.user.email} a mis à jour le groupe de travail `}</span>
          "<WorkgroupLink workgroupId={evt.objectId} />".
        </React.Fragment> 
      );
    },
    "dsf": (evt:Event) => {
      return (
        <React.Fragment>
          <span>{`${evt.user.name ? evt.user.name : evt.user.email} a modifié le dossier d'aide à la décision `}</span>
          "<DecisioSupportFileLink decisionSupportFileId={evt.objectId} />".
        </React.Fragment>
      );
    },
  },
  "leaved": {
    "workgroup": (evt:Event) => {
      return (
        <React.Fragment>
          <span>{`${evt.user.name ? evt.user.name : evt.user.email} a quitté le groupe de travail `}</span>
          "<WorkgroupLink workgroupId={evt.objectId} />".
        </React.Fragment> 
      );
    },
  },
  "closed": {
    "workgroup": (evt:Event) => {
      return (
        <React.Fragment>
          <span>{`${evt.user.name ? evt.user.name : evt.user.email} a clos le groupe de travail `}</span>
          "<WorkgroupLink workgroupId={evt.objectId} />".
        </React.Fragment> 
      );
    },
  },
};

function renderEventContent(evt: Event) {
  const eventTypeMap = eventContentMap[evt.type];
  const render = eventTypeMap && eventTypeMap[evt.objectType];
  
  if (!eventTypeMap || !render) {
    return (
      <span className="is-italic">{`Type d'évènement "${evt.type}/${evt.objectType}" inconnu.`}</span>
    );
  }

  return render(evt);
}