// imports
import React, { useMemo, useState } from 'react';

// locals
import Diff from './Diff';
import Input from '../Input';
import Button from '../Button';
import Overlay from '../Overlay';
import useTeam from '../../hooks/useTeam';
import ApiSignal from '../../signals/Api';
import { myersDiff } from '../../utilities/diff';
import { useBranches } from '../../data/useBranch';
import Signal, { useSignal } from '../../signal';

// open
export const commit = new Signal.State(null);
export const remove = new Signal.State(null);
export const onCommitUpdate = new Signal.State(null);

/**
 * component commit modal
 *
 * @param props 
 */
const ComponentCommitModal = (props = {}) => {
  // signals
  const [api] = useSignal(ApiSignal);
  const [sOnCommitUpdate] = useSignal(onCommitUpdate);
  const [sCommit, setCommit] = useSignal(commit);

  // team
  const team = useTeam();

  // use branches
  const { branches } = useBranches({
    team     : sCommit?.team || team?.id,
    workflow : sCommit?.workflow,
  }, {
    disable : !sCommit?.workflow || !team?.id,
  });

  // state
  const [saving, setSaving] = useState(false);

  // create diff
  const diff = useMemo(() => {
    // check diffs
    if (!sCommit?.current || !sCommit?.value) return null;

    // return diff
    return myersDiff(sCommit.current, sCommit.value);
  }, [sCommit?.value, sCommit?.current])

  // on save
  const onSave = async () => {
    // save commit
    if (saving) return;

    // set saving
    setSaving(true);

    // try/catch
    try {
      // save commit
      const result = await api.Commit[sCommit?.id ? 'update' : 'create']({
        ...sCommit,
        team : team?.id,
      });

      // on commit save
      if (sOnCommitUpdate) sOnCommitUpdate(result.commit, branches.find(branch => branch.id === result.commit.branch));
    } catch (e) {
      // log
      console.error(e);
    } finally {
      // set saving
      setCommit(null);
      setSaving(false);
    }
  };

  // return jsx
  return (
    <Overlay
      open={!!sCommit}
      title={api.translate('commit:dialog.title', 'Create Commit')}
      onClose={() => setCommit(null)}
      subtitle={api.translate('commit:dialog.subtitle', 'Create a new commit for your workflow')}
    >
      <Input
        name="message"
        type="text"
        label={api.translate('commit:form.message.label', 'Commit Message')}
        value={sCommit?.message || ''}
        onChange={(e) => setCommit({ ...sCommit, message: e.target.value })}
        placeholder={api.translate('commit:form.message.placeholder', 'Enter a descriptive commit message')}
      />
      
      <Input
        name="branch"
        type="select"
        label={api.translate('commit:form.branch.label', 'Branch')}
        value={sCommit?.branch || ''}
        onChange={(e) => setCommit({ ...sCommit, branch: e.target.value })}
        placeholder={api.translate('commit:form.branch.placeholder', 'Select the branch')}
      >
        {branches.map(branch => (
          <option key={branch.id} value={branch.id}>
            {branch.name}
          </option>
        ))}
      </Input>

      {!!diff?.length && (
        <Diff diff={diff} />
      )}
      
      <div className="pt-4 sm:pt-6 sm:flex sm:flex-row-reverse">
        <Button
          color="primary"
          onClick={onSave}
          loading={saving}
          disabled={!sCommit?.message || !sCommit?.value}
        >
          {saving ? api.translate('commit:button.loading', 'Loading...') : api.translate('commit:button.submit', 'Submit')}
        </Button>
        <Button
          color="transparent"
          onClick={() => setCommit(null)}
        >
          {api.translate('commit:button.cancel', 'Cancel')}
        </Button>
      </div>
    </Overlay>
  )
};

/**
 * export component commit modal
 */
export default ComponentCommitModal;