const fields = [
  { fieldName: 'KorName', dataType: 'text' },
  { fieldName: 'Gender', dataType: 'text' },
  { fieldName: 'Age', dataType: 'number' },
  { fieldName: 'Phone', dataType: 'text' },
  { fieldName: 'ProductId', dataType: 'text' },
  { fieldName: 'KorCountry', dataType: 'text' },
  { fieldName: 'OrderDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'CardNumber', dataType: 'text' },
  { fieldName: 'Monetary', dataType: 'text' },
  { fieldName: 'StartDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'EndDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'ToMonth', dataType: 'number' },
  { fieldName: 'Month', dataType: 'number' },
  { fieldName: 'Year', dataType: 'number' },
  { fieldName: 'InterestRate', dataType: 'number' },
  { fieldName: 'SaveCost', dataType: 'number' },
  { fieldName: 'SaveMaturity', dataType: 'number' },
  { fieldName: 'CurrentSave', dataType: 'number' },
  { fieldName: 'FileDownload', dataType: 'text' },
  { fieldName: 'Files', dataType: 'object' }
];

const columns = [
  { name: 'KorName', fieldName: 'KorName', width: '60', header: { text: 'Name' } },
  { name: 'Gender', fieldName: 'Gender', width: '40', header: { text: 'Gender' } },
  { name: 'Age', fieldName: 'Age', width: '40', header: { text: 'Age' }, styleName: 'right-column' },
  { name: 'Phone', fieldName: 'Phone', width: '100', header: { text: 'Phone' } },
  { name: 'ProductId', fieldName: 'ProductId', width: '120', header: { text: 'Product ID' } },
  { name: 'KorCountry', fieldName: 'KorCountry', width: '100', header: { text: 'Investment Country' } },
  { name: 'OrderDate', fieldName: 'OrderDate', width: '100', header: { text: 'Order Date' } },
  { name: 'CardNumber', fieldName: 'CardNumber', width: '140', header: { text: 'Card Number' } },
  { name: 'Monetary', fieldName: 'Monetary', width: '40', header: { text: 'Currency' } },
  {
    name: 'FileDownload',
    fieldName: 'FileDownload',
    width: '160',
    header: { text: 'Download Attachment' },
    editable: false,
    styleName: 'left-column',
    renderer: {
      type: 'html',
      callback: function(grid, cell, w, h) {
        let str = '';
        const dataRow = cell.index.dataRow;
        const fileValue = grid.getDataSource().getValue(dataRow, 'Files');
        
        if (fileValue) {
          for (let i = 0; i < fileValue.length; i++) {
            const fileName = "'" + fileValue[i].fileName + "'";
            const aTag = " <a download='" + fileValue[i].fileName + "' href='data:application/octet-stream;base64," + fileValue[i].base64Data + "'>" + fileValue[i].fileName + '</a><br>';
            str = str + '<a href="javascript:void(0);" class="btn" onclick="fileDelete(this)" datarow=' + dataRow + ' filename=' + fileName + '>X</a>' + aTag;
          }
        }
        return str;
      }
    }
  }
];

const { gridView, dataProvider } = RealGrid.createGrid("realgrid", {
  columns,
  header: {
    height: 40
  },
  display: {
    rowHeight: -1,
    minRowHeight: 35,
    emptyMessage: "No data to display.",
    fitStyle: 'evenFill'
  },
  edit: {
    insertable: true,
    appendable: true
  },
  footer: {
    height: 40
  },
  stateBar: {
    width: 16
  },
  onInitialized: (grid) => {
    fetch('/data/en/simple_data.json')
      .then(response => response.json())
      .then(data => {
        grid.getDataSource().setRows(data);
        grid.refresh();
      });
  }
}, {
  fields
});

const gridContainer = gridView.getContainer();
let outputs = [];
let files = [];

function fileTobase64(index, cellIndex) {
  if (files.length > index) {
    const file = files[index];
    const reader = new FileReader();

    reader.onload = function() {
      const text = reader.result;
      const file = files[index];
      
      const outs = {};
      outs['fileName'] = file.name;
      outs['dataURL'] = text;
      outs['base64Data'] = text.substring(text.indexOf(',') + 1);

      outputs.push(outs);
      
      if (files.length > (index + 1)) {
        fileTobase64(index + 1, cellIndex);
      } else {
        dataProvider.setValue(cellIndex.dataRow, 'Files', outputs);
      }
    };
    reader.readAsDataURL(file);
  }
}

function dragEnterHandler(ev) {
  gridContainer.querySelectorAll('.rg-data-cell').forEach(element => {
    element.ondragenter = (event) => {
      element.classList.add('drag-over-cell');
    };
    element.ondragleave = (event) => {
      const relatedTarget = event.relatedTarget;
      if (!relatedTarget || !element.contains(relatedTarget)) {
        element.classList.remove('drag-over-cell');
      }
    };
    element.ondrop = element.ondragover = (event) => {
      event.preventDefault();
    };
  });
}

function dragLeaveHandler(ev) {
  if (!ev.relatedTarget || !gridContainer.contains(ev.relatedTarget)) {
    gridContainer.querySelectorAll('.rg-data-cell').forEach(element => {
      element.classList.remove('drag-over-cell');
    });
  }
}

function dragOverHandler(ev) {
  ev.preventDefault();
}

function dropHandler(ev) {
  ev.preventDefault();
  
  gridContainer.querySelectorAll('.rg-data-cell').forEach(element => {
    element.ondrop = element.ondragenter = element.ondragleave = element.ondragover = null;
    element.classList.remove('drag-over-cell');
  });

  const cellIndex = gridView.mouseToIndex(ev.clientX, ev.clientY, true);

  if (cellIndex.dataRow === -1) {
    alert('Drop the file in the exact location.');
    return false;
  }

  if (ev.dataTransfer.items) {
    outputs = [];
    files = [];
    for (let i = 0; i < ev.dataTransfer.items.length; i++) {
      files.push(ev.dataTransfer.items[i].getAsFile());
    }
    fileTobase64(0, cellIndex);
  }
}

function fileDelete(el) {
  const dataRow = parseInt(el.getAttribute('datarow'));
  let fileName = el.getAttribute('filename');
  // Remove surrounding quotes if present
  if (fileName && fileName.startsWith("'") && fileName.endsWith("'")) {
    fileName = fileName.substring(1, fileName.length - 1);
  }

  let filesData = dataProvider.getValue(dataRow, 'Files');
  filesData = filesData.filter(function(obj) {
    return obj.fileName !== fileName;
  });
  dataProvider.setValue(dataRow, 'Files', filesData);
}

const realgridDiv = document.getElementById('realgrid');
realgridDiv.ondragenter = dragEnterHandler;
realgridDiv.ondragleave = dragLeaveHandler;
realgridDiv.ondrop = dropHandler;
realgridDiv.ondragover = dragOverHandler;

window.gridView = gridView;
window.dataProvider = dataProvider;