const createInputTextArea = (label, placeholder = '') => {
  const id = UTILS.generateGuid('comp');
  const container = $('<div>', {class: 'uk-margin-small'});
  const fc = $('<div>', {class: 'uk-form-controls'});
  const textarea = $(`<textarea id="${id}" class="uk-textarea" rows="2" placeholder="${placeholder}"></textarea>`);
  fc.append(textarea);
  container.append(`<label class="uk-form-label" for="${id}">${label}</label>`, fc);
  return {container, textarea};
}

const createInputText = (label, placeholder = '') => {
  const id = UTILS.generateGuid('comp');
  const container = $('<div>', {class: 'uk-margin-small'});
  const fc = $('<div>', {class: 'uk-form-controls'});
  const input = $(`<input type="text" id="${id}" class="uk-input" placeholder="${placeholder}">`);
  fc.append(input);
  container.append(`<label class="uk-form-label" for="${id}">${label}</label>`, fc);
  return {container, input};
}

const createInputPassword = (label = '') => {
  const id = UTILS.generateGuid('comp');
  const container = $('<div>', {class: 'uk-margin-small'});
  const fc = $('<div>', {class: 'uk-form-controls'});

  const inline = $('<div>', {
    class: 'uk-inline',
    style: 'width: 100%;'
  });
  const icon = $(`<span>`, {
    class: 'uk-form-icon uk-form-icon-flip material-icons',
    style: 'display: flex; pointer-events: all; cursor: pointer;'
  })
  const input = $(`<input>`, {type: "password", id, class: "uk-input"});

  let hidePass = true;
  icon.on('click', e => {
    if(hidePass) {
      input.attr('type', 'text');
      icon.text('visibility_off');
    } else {
      input.attr('type', 'password');
      icon.text('visibility');
    }
    hidePass = !hidePass;
  });

  icon.text('visibility');
  inline.append(icon, input);
  fc.append(inline);
  container.append(`<label class="uk-form-label" for="${id}">${label}</label>`, fc);
  return {container, input};
}

const createInputNumber = (label, placeholder = '') => {
  const id = UTILS.generateGuid('comp');
  const container = $('<div>', {class: 'uk-margin-small'});
  const fc = $('<div>', {class: 'uk-form-controls'});
  const input = $(`<input type="number" id="${id}" class="uk-input" placeholder="${placeholder}">`);
  fc.append(input);
  container.append(`<label class="uk-form-label" for="${id}">${label}</label>`).append(fc);
  return {container, input};
}

const createCheckbox = (label) => {
  const id = UTILS.generateGuid('comp');
  const container = $('<div>', {class: 'uk-margin-small'});
  const input = $(`<input type="checkbox" id="${id}" class="uk-checkbox">`);
  container.append($(`<label class="uk-form-label" for="${id}"></label>`).append(input, ` ${label}`));
  return {container, input};
}

const getInputDateTime = (d, t) => $(`<input type="date" class="uk-input" style="max-width: 140px;" value="${d || ''}"><input type="time" class="uk-input" style="max-width: 100px;" value="${t || ''}">`);

const getInputDate = d => $(`<input type="date" class="uk-input" style="max-width: 140px;" value="${d || ''}">`);

const createDatePeriod = (label, start_date, finish_date) => {
  start_date = start_date.split(' ');
  finish_date = finish_date.split(' ');
  const container = $('<div>', {class: 'uk-margin-small'});
  const fc = $('<div>', {class: 'uk-form-controls'});
  const dateStart = getInputDateTime(start_date[0], start_date[1]);
  const dateFinish = getInputDateTime(finish_date[0], finish_date[1]);
  fc.append(dateStart).append('<label style="margin: 0 10px;">-</label>').append(dateFinish);
  container.append(`<label class="uk-form-label">${label}</label>`, fc);
  return {container, dateStart, dateFinish};
}

const createDateInput = (label, date) => {
  const container = $('<div>', {class: 'uk-margin-small'});
  const fc = $('<div>', {class: 'uk-form-controls'});
  const dateInput = getInputDate(date);
  fc.append(dateInput);
  container.append(`<label class="uk-form-label">${label}</label>`, fc);
  return {container, dateInput};
}

const createDateTimeInput = (label, date) => {
  date = date.split(' ');
  const container = $('<div>', {class: 'uk-margin-small'});
  const fc = $('<div>', {class: 'uk-form-controls'});
  const dateTimeInput = getInputDateTime(date[0], date[1]);
  fc.append(dateTimeInput);
  container.append(`<label class="uk-form-label">${label}</label>`, fc);
  return {container, dateTimeInput};
}

const createSelectComponent = (label, items, multiple = false) => {
  const container = $('<div>', {class: 'uk-margin-small'});
  const fc = $('<div>', {class: 'uk-form-controls'});
  const select = $('<select class="uk-select" style="min-width: 100px;">');

  if(multiple) select.attr('multiple', 'multiple');
  if(items) items.sort((a,b) => a.value - b.value)
  .forEach(item => select.append(`<option value="${item.value}" title="${item.label}">${item.label}</option>`));

  fc.append(select);
  container.append(`<label class="uk-form-label">${label}</label>`, fc);

  return {container, select};
}

const createDropdownNav = (items, mode) => {
  const button = $('<button>', {class: 'uk-button uk-button-default'});
  const dropdown = $(`<div uk-dropdown="mode: ${mode}">`);
  const nav = $('<ul>', {class: 'uk-nav uk-navbar-dropdown-nav'});
  items.forEach(item => nav.append(`<li><a href="#" itemvalue="${item.value}">${item.label}</a></li>`));
  dropdown.append(nav);
  return {button, dropdown};
}

const createUserParamBlock = (label, type, workData, multiSelectable = false, filterDepartmentID = null) => {
  const fc = $('<div>', {class: 'uk-form-controls'});
  const button = $('<a class="uk-form-icon uk-form-icon-flip" href="javascript:void(0);" uk-icon="icon: users"></a>');
  const input = $('<input class="uk-input" type="text" disabled>');
  const values = workData[type] || null;

  fc.append($('<div class="uk-inline uk-width-expand">').append(button, input));

  if(values) {
    let userNames = values.map(x => x.personName).join('; ');
    input.val(userNames).attr('title', userNames);
  }

  button.on('click', e => {
    //(values, multiSelectable, isGroupSelectable, showWithoutPosition, filterPositionID, filterDepartmentID, locale, handler)
    AS.SERVICES.showUserChooserDialog(values, multiSelectable, false, false, null, filterDepartmentID, AS.OPTIONS.locale, users => {
      let userNames = users.map(x => x.personName).join('; ');
      input.val(userNames).attr('title', userNames);
      workData[type] = users;
    });
  });

  return $('<div>', {class: 'uk-margin-small'}).append(`<label class="uk-form-label">${label}</label>`, fc);
}

const createSelectFile = label => {
  const container = $('<div>', {class: 'uk-margin-small'});
  const fc = $('<div uk-form-custom="target: true" style="width: 100%;" class="uk-inline">');
  const icon = $('<span class="uk-form-icon uk-form-icon-flip" uk-icon="icon: more"></span>');
  const inputFile = $('<input type="file">');

  fc.append(icon).append(inputFile).append(`<input class="uk-input uk-form-width-medium" type="text" style="font-size: 14px; color: #333; background: #fff; min-width: 245px; width: 100%;" disabled>`);
  container.append(`<label class="uk-form-label">${label}</label>`, fc);

  return {container, inputFile};
}

const createSelectFileMultiple = buttonName => {
  const container = $('<div>', {class: 'uk-margin-small'});
  const fc = $('<div uk-form-custom="target: true" style="width: 100%;" class="uk-inline">');
  const inputFile = $('<input type="file" multiple>');

  fc.append(inputFile, `<button class="uk-button uk-button-default" type="button" tabindex="-1">${buttonName}</button>`);
  container.append(fc);

  return {container, inputFile};
}

const createAccordion = (data, customClass) => {
  const container = $('<ul uk-accordion="multiple: true" style="width: 100%;">');
  if(customClass) container.addClass(customClass);

  for(let i = 0; i < data.length; i++) {
    const {title, content, open} = data[i];
    const titleTranslate = i18n.tr(title);
    const li = $('<li>');
    const accContent = $('<div>', {class: 'uk-accordion-content'}).append(content);
    if(open) li.addClass('uk-open');
    li.append(`<a class="uk-accordion-title" href="#">${titleTranslate}</a>`, accContent);
    container.append(li);
  }

  return container;
}

const createTable = (data, classes = []) => {
  const {headers, rows} = data;
  const container = $('<div>');
  const table = $('<table>', {class: "uk-table"});
  const thead = $('<thead>');
  const tbody = $('<tbody>');
  const theadTr = $('<tr>');

  classes.forEach(addClass => table.addClass(addClass));

  headers.forEach(header => theadTr.append(`<th>${header}</th>`));

  rows.forEach(row => {
    const tr = $('<tr>');
    tbody.append(tr);
    row.forEach(text => {
      const td = $('<td>');
      td.html(text);
      tr.append(td);
    });
  });

  thead.append(theadTr);
  table.append(thead).append(tbody);
  container.append(table);

  return {container, table};
}

this.Components = {
  createInputTextArea,
  createInputText,
  createInputNumber,
  createInputPassword,
  createUserParamBlock,
  createDateInput,
  createDateTimeInput,
  createDatePeriod,
  createSelectComponent,
  createAccordion,
  createTable,
  createDropdownNav,
  createSelectFile,
  createSelectFileMultiple,
  createCheckbox,

  create: async function(type, workData, defaultParamWork) {
    const {systemSettings} = Cons.getAppStore();
    const {current_priorities, work_completion_forms} = systemSettings;

    switch (type) {
      case 'NAME':
        workData[type] = '';
        const workNamePlaceholder = i18n.tr("Введите формулировку работы");
        const workNameLabel = i18n.tr("Название");
        const {container: workContainer, textarea: workName} = createInputTextArea(workNameLabel, workNamePlaceholder);
        workName.on('change', e => {
          workData[type] = workName.val();
        });
        return workContainer;
      break;

      case 'COMMENT':
        workData[type] = '';
        const commentPlaceholder = i18n.tr("Данный комментарий будет добавлен к созданной работе");
        const commentLabel = i18n.tr("Комментарий к работе");
        const {container: commentContainer, textarea: commentName} = createInputTextArea(commentLabel, commentPlaceholder);
        commentName.on('change', e => {
          workData[type] = commentName.val();
        });
        return commentContainer;
      break;

      case 'DATES':
        const {start_date, finish_date} = defaultParamWork;
        workData[type] = {start: start_date, finish: finish_date};
        const {container: workPeriodContainer, dateStart, dateFinish} = createDatePeriod(i18n.tr("Сроки"), start_date, finish_date);

        $(dateStart[0]).on('change', e => workData[type].start = `${$(dateStart[0]).val()} ${$(dateStart[1]).val()}:00`.slice(0, 19));
        $(dateStart[1]).on('change', e => workData[type].start = `${$(dateStart[0]).val()} ${$(dateStart[1]).val()}:00`.slice(0, 19));
        $(dateFinish[0]).on('change', e => workData[type].finish = `${$(dateFinish[0]).val()} ${$(dateFinish[1]).val()}:00`.slice(0, 19));
        $(dateFinish[1]).on('change', e => workData[type].finish = `${$(dateFinish[0]).val()} ${$(dateFinish[1]).val()}:00`.slice(0, 19));
        return workPeriodContainer;
      break;

      case 'RESPONSIBLE':
        workData[type] = null;
        return createUserParamBlock(i18n.tr("Ответственный"), type, workData);
      break;

      case 'USERS':
        workData[type] = null;
        return createUserParamBlock(i18n.tr("Исполнители"), type, workData, true);
      break;

      case 'PRIORITY':
        const priorities = current_priorities.map(x => {
          return {label: x.name, value: x.id};
        });
        const {container: prioritetContainer, select: prioritetSelect} = createSelectComponent(i18n.tr("Приоритет"), priorities);
        workData[type] = priorities[0];
        prioritetSelect.on('change', e => {
          workData[type] = priorities.find(x => x.value == prioritetSelect.val());
        });
        return prioritetContainer;
      break;

      case 'COMPLETION_FORM':
        const completionForms = work_completion_forms.map(x => {
          return {label: x.name, value: x.id, code: x.code};
        });
        completionForms.unshift({label: i18n.tr('Нет'), value: '', code: ''});
        const {container: completionFormsContainer, select: completionFormsSelect} = createSelectComponent(i18n.tr("Форма завершения"), completionForms);
        workData[type] = completionForms[0];
        completionFormsSelect.on('change', e => {
          workData[type] = completionForms.find(x => x.value == completionFormsSelect.val());
        });
        return completionFormsContainer;
      break;

      case 'ATTACH_FILE':
        workData[type] = null;
        return createSelectFile(i18n.tr("Прикрепить документ"), type, workData);
      break;
    }
  }
}
