import { createElement, lazy } from 'react'

const GCodeFileInfo = lazy(
  () => import('../../components/Dashboard/Production/GCodeFiles/GCodeFileInfo')
)
import DownloadIcon from '../../components/Icons/DownloadIcon'
import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import GCodeFileIcon from '../../components/Icons/GCodeFileIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EyeIcon from '../../components/Icons/EyeIcon'

export const GCodeFile = {
  name: 'gcodeFile',
  label: 'GCode File',
  labelPlural: 'GCode Files',
  url: '/dashboard/production/gcodefiles',
  prefix: 'GCF',
  icon: GCodeFileIcon,
  actions: [
    {
      name: 'preview',
      label: 'Preview',
      row: true,
      icon: EyeIcon,
      url: (_id) =>
        `/dashboard/production/gcodefiles/preview?gcodeFileId=${_id}`
    },
    {
      name: 'info',
      type: 'page',
      pageName: 'info',
      label: 'Info',
      default: true,
      row: true,
      icon: InfoCircleIcon
    },
    {
      name: 'download',
      type: 'page',
      pageName: 'info',
      label: 'Download',
      row: true,
      icon: DownloadIcon
    },
    {
      name: 'edit',
      type: 'page',
      pageName: 'info',
      label: 'Edit',
      row: true,
      icon: EditIcon,
      visible: (objectData) => {
        return !(objectData?._isEditing && objectData?._isEditing == true)
      }
    },
    {
      name: 'cancelEdit',
      label: 'Cancel Edits',
      type: 'page',
      pageName: 'info',
      icon: XMarkIcon,
      visible: (objectData) => {
        return objectData?._isEditing && objectData?._isEditing == true
      }
    },
    {
      name: 'finishEdit',
      label: 'Save Edits',
      type: 'page',
      pageName: 'info',
      icon: CheckIcon,
      visible: (objectData) => {
        return objectData?._isEditing && objectData?._isEditing == true
      }
    }
  ],
  pages: [
    {
      name: 'info',
      content: () => createElement(GCodeFileInfo)
    }
  ],

  columns: [
    '_reference',
    'name',
    'filament',
    'filamentSku',
    'cost',
    'gcodeFileInfo.estimatedPrintingTimeNormalMode',
    'gcodeFileInfo.sparseInfillDensity',
    'gcodeFileInfo.sparseInfillPattern',
    'gcodeFileInfo.nozzleTemperature',
    'gcodeFileInfo.hotPlateTemp',
    'createdAt',
    'updatedAt'
  ],
  filters: [
    '_id',
    'name',
    'filament',
    'filament._id',
    'filamentSku',
    'filamentSku._id',
    'createdAt',
    'updatedAt',
    '_reference'
  ],
  sorters: [
    'name',
    'filament',
    'filamentSku',
    'cost',
    'createdAt',
    'updatedAt'
  ],
  group: ['filament', 'filamentSku'],
  properties: [
    {
      name: '_id',
      label: 'ID',
      type: 'id',
      objectType: 'gcodeFile',
      columnFixed: 'left',
      value: null,
      showCopy: true,
      columnWidth: 140
    },
    {
      name: 'createdAt',
      label: 'Created At',
      type: 'dateTime',
      value: null,
      readOnly: true,
      columnWidth: 175
    },
    {
      name: '_reference',
      label: 'Reference',
      type: 'reference',
      columnFixed: 'left',
      objectType: 'gcodeFile',
      showCopy: true,
      readOnly: true,
      columnWidth: 180
    },
    {
      name: 'updatedAt',
      label: 'Updated At',
      type: 'dateTime',
      value: null,
      readOnly: true,
      columnWidth: 175
    },
    {
      name: 'name',
      label: 'Name',
      columnFixed: 'left',
      type: 'text',
      required: true,
      columnWidth: 200,
      value: (objectData) => {
        if (objectData?.name == undefined) {
          return objectData?.file?.name
        }
        return objectData?.name
      }
    },
    {
      name: 'file',
      label: 'File',
      type: 'file',
      value: null,
      required: true,
      showPreview: false,
      showHyperlink: true,
      masterFilter: ['.gcode', '.g'],
      thumbnail: true,
      columnWidth: 200
    },
    {
      name: 'filament',
      label: 'Filament',
      type: 'object',
      value: null,
      objectType: 'filament',
      required: true,
      showHyperlink: true,
      columnWidth: 200
    },
    {
      name: 'filamentSku',
      label: 'Filament SKU',
      type: 'object',
      value: null,
      objectType: 'filamentSku',
      required: true,
      showHyperlink: true,
      columnWidth: 200,
      masterFilter: (objectData) => {
        return {
          filament: objectData?.filament?._id
        }
      }
    },
    {
      name: 'cost',
      label: 'Cost',
      type: 'number',
      roundNumber: 2,
      value: (objectData) => {
        const fs = objectData?.filamentSku
        const costPerKg = fs?.overrideCost ? fs?.cost : fs?.filament?.cost
        if (!costPerKg || !objectData?.file?.metaData?.filamentUsedG)
          return undefined
        return objectData.file.metaData.filamentUsedG * (costPerKg / 1000)
      },
      readOnly: true,
      prefix: '£',
      columnWidth: 100
    },
    {
      name: 'file.metaData.filamentUsedG',
      label: 'Est Print Time',
      value: null,
      type: 'text',
      readOnly: true,
      columnWidth: 130
    },
    {
      name: 'file.metaData.sparseInfillDensity',
      label: 'Infill Density',
      columnWidth: 150,
      type: 'text',
      readOnly: true
    },
    {
      name: 'file.metaData.sparseInfillPattern',
      label: 'Infill Pattern',
      type: 'text',
      readOnly: true,
      columnWidth: 150
    },
    {
      name: 'file.metaData.filamentUsedMm',
      label: 'Filament Used (mm)',
      type: 'number',
      readOnly: true,
      suffix: 'mm',
      columnWidth: 160
    },
    {
      name: 'file.metaData.filamentUsedG',
      label: 'Filament Used (g)',
      type: 'number',
      suffix: 'g',
      readOnly: true,
      columnWidth: 150
    },
    {
      name: 'file.metaData.nozzleTemperature',
      label: 'Hotend Temp',
      columnWidth: 150,
      type: 'number',
      suffix: '°',
      readOnly: true
    },
    {
      name: 'file.metaData.hotPlateTemp',
      label: 'Bed Temp',
      columnWidth: 150,
      type: 'number',
      suffix: '°',
      readOnly: true
    },
    {
      name: 'file.metaData.filamentSettingsId',
      label: 'Filament Profile',
      type: 'text',
      readOnly: true,
      columnWidth: 150
    },
    {
      name: 'file.metaData.printSettingsId',
      label: 'Print Profile',
      type: 'text',
      readOnly: true,
      columnWidth: 150
    },
    {
      name: 'parts',
      label: 'Parts',
      type: 'objectChildren',
      objectType: 'part',
      size: 'medium',
      properties: [
        {
          name: 'part',
          label: 'Part',
          type: 'object',
          objectType: 'part',
          required: true,
          showHyperlink: true
        },
        {
          name: 'partSku',
          label: 'Part SKU',
          type: 'object',
          objectType: 'partSku',
          required: true,
          showHyperlink: true,
          masterFilter: (objectData) => {
            const partId = objectData?.part?._id
            if (partId == null) return {}
            return { part: partId }
          }
        },
        {
          name: 'quantity',
          label: 'Quantity',
          type: 'number',
          required: true
        }
      ],
      rollups: [
        {
          name: 'totalQuantity',
          label: 'Total',
          type: 'number',
          property: 'quantity',
          value: (objectData) => {
            return objectData?.parts?.reduce(
              (acc, part) => acc + part.quantity,
              0
            )
          }
        }
      ]
    }
  ]
}
