import { mergeProps as _mergeProps, createVNode as _createVNode, Fragment as _Fragment } from "vue";
// Styles
import "./VFileUpload.css";

// Components
import { VFileUploadItem } from "./VFileUploadItem.mjs";
import { VBtn } from "../../components/VBtn/VBtn.mjs";
import { VDefaultsProvider } from "../../components/VDefaultsProvider/VDefaultsProvider.mjs";
import { makeVDividerProps, VDivider } from "../../components/VDivider/VDivider.mjs";
import { VIcon } from "../../components/VIcon/VIcon.mjs";
import { VOverlay } from "../../components/VOverlay/VOverlay.mjs";
import { makeVSheetProps, VSheet } from "../../components/VSheet/VSheet.mjs"; // Composables
import { makeDelayProps } from "../../composables/delay.mjs";
import { makeDensityProps, useDensity } from "../../composables/density.mjs";
import { IconValue } from "../../composables/icons.mjs";
import { useLocale } from "../../composables/locale.mjs";
import { useProxiedModel } from "../../composables/proxiedModel.mjs"; // Utilities
import { onMounted, onUnmounted, ref, shallowRef } from 'vue';
import { filterInputAttrs, genericComponent, pick, propsFactory, useRender, wrapInArray } from "../../util/index.mjs"; // Types
export const makeVFileUploadProps = propsFactory({
  browseText: {
    type: String,
    default: '$vuetify.fileUpload.browse'
  },
  dividerText: {
    type: String,
    default: '$vuetify.fileUpload.divider'
  },
  title: {
    type: String,
    default: '$vuetify.fileUpload.title'
  },
  subtitle: String,
  icon: {
    type: IconValue,
    default: '$upload'
  },
  modelValue: {
    type: [Array, Object],
    default: null,
    validator: val => {
      return wrapInArray(val).every(v => v != null && typeof v === 'object');
    }
  },
  clearable: Boolean,
  disabled: Boolean,
  hideBrowse: Boolean,
  multiple: Boolean,
  scrim: {
    type: [Boolean, String],
    default: true
  },
  showSize: Boolean,
  name: String,
  ...makeDelayProps(),
  ...makeDensityProps(),
  ...pick(makeVDividerProps({
    length: 150
  }), ['length', 'thickness', 'opacity']),
  ...makeVSheetProps()
}, 'VFileUpload');
export const VFileUpload = genericComponent()({
  name: 'VFileUpload',
  inheritAttrs: false,
  props: makeVFileUploadProps(),
  emits: {
    'update:modelValue': files => true
  },
  setup(props, _ref) {
    let {
      attrs,
      slots
    } = _ref;
    const {
      t
    } = useLocale();
    const {
      densityClasses
    } = useDensity(props);
    const model = useProxiedModel(props, 'modelValue', props.modelValue, val => wrapInArray(val), val => props.multiple || Array.isArray(props.modelValue) ? val : val[0]);
    const dragOver = shallowRef(false);
    const vSheetRef = ref(null);
    const inputRef = ref(null);
    onMounted(() => {
      vSheetRef.value?.$el.addEventListener('dragover', onDragOver);
      vSheetRef.value?.$el.addEventListener('drop', onDrop);
    });
    onUnmounted(() => {
      vSheetRef.value?.$el.removeEventListener('dragover', onDragOver);
      vSheetRef.value?.$el.removeEventListener('drop', onDrop);
    });
    function onDragOver(e) {
      e.preventDefault();
      e.stopImmediatePropagation();
      dragOver.value = true;
    }
    function onDragLeave(e) {
      e.preventDefault();
      dragOver.value = false;
    }
    function onDrop(e) {
      e.preventDefault();
      e.stopImmediatePropagation();
      dragOver.value = false;
      const files = Array.from(e.dataTransfer?.files ?? []);
      if (!files.length) return;
      if (!props.multiple) {
        model.value = [files[0]];
        return;
      }
      const array = model.value.slice();
      for (const file of files) {
        if (!array.some(f => f.name === file.name)) {
          array.push(file);
        }
      }
      model.value = array;
    }
    function onClick() {
      inputRef.value?.click();
    }
    function onClickRemove(index) {
      model.value = model.value.filter((_, i) => i !== index);
      if (model.value.length > 0 || !inputRef.value) return;
      inputRef.value.value = '';
    }
    useRender(() => {
      const hasTitle = !!(slots.title || props.title);
      const hasIcon = !!(slots.icon || props.icon);
      const hasBrowse = !!(!props.hideBrowse && (slots.browse || props.density === 'default'));
      const cardProps = VSheet.filterProps(props);
      const dividerProps = VDivider.filterProps(props);
      const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
      const inputNode = _createVNode("input", _mergeProps({
        "ref": inputRef,
        "type": "file",
        "disabled": props.disabled,
        "multiple": props.multiple,
        "name": props.name,
        "onChange": e => {
          if (!e.target) return;
          const target = e.target;
          model.value = [...(target.files ?? [])];
        }
      }, inputAttrs), null);
      return _createVNode(_Fragment, null, [_createVNode(VSheet, _mergeProps({
        "ref": vSheetRef
      }, cardProps, {
        "class": ['v-file-upload', {
          'v-file-upload--clickable': !hasBrowse,
          'v-file-upload--disabled': props.disabled,
          'v-file-upload--dragging': dragOver.value
        }, densityClasses.value],
        "onDragleave": onDragLeave,
        "onDragover": onDragOver,
        "onDrop": onDrop,
        "onClick": !hasBrowse ? onClick : undefined
      }, rootAttrs), {
        default: () => [hasIcon && _createVNode("div", {
          "key": "icon",
          "class": "v-file-upload-icon"
        }, [!slots.icon ? _createVNode(VIcon, {
          "key": "icon-icon",
          "icon": props.icon
        }, null) : _createVNode(VDefaultsProvider, {
          "key": "icon-defaults",
          "defaults": {
            VIcon: {
              icon: props.icon
            }
          }
        }, {
          default: () => [slots.icon()]
        })]), hasTitle && _createVNode("div", {
          "key": "title",
          "class": "v-file-upload-title"
        }, [slots.title?.() ?? t(props.title)]), props.density === 'default' && _createVNode(_Fragment, null, [_createVNode("div", {
          "key": "upload-divider",
          "class": "v-file-upload-divider"
        }, [slots.divider?.() ?? _createVNode(VDivider, dividerProps, {
          default: () => [t(props.dividerText)]
        })]), hasBrowse && _createVNode(_Fragment, null, [!slots.browse ? _createVNode(VBtn, {
          "readonly": props.disabled,
          "size": "large",
          "text": t(props.browseText),
          "variant": "tonal",
          "onClick": onClick
        }, null) : _createVNode(VDefaultsProvider, {
          "defaults": {
            VBtn: {
              readonly: props.disabled,
              size: 'large',
              text: t(props.browseText),
              variant: 'tonal'
            }
          }
        }, {
          default: () => [slots.browse({
            props: {
              onClick
            }
          })]
        })]), props.subtitle && _createVNode("div", {
          "class": "v-file-upload-subtitle"
        }, [props.subtitle])]), _createVNode(VOverlay, {
          "model-value": dragOver.value,
          "contained": true,
          "scrim": props.scrim
        }, null), slots.input?.({
          inputNode
        }) ?? inputNode]
      }), model.value.length > 0 && _createVNode("div", {
        "class": "v-file-upload-items"
      }, [model.value.map((file, i) => {
        const slotProps = {
          file,
          props: {
            'onClick:remove': () => onClickRemove(i)
          }
        };
        return _createVNode(VDefaultsProvider, {
          "key": i,
          "defaults": {
            VFileUploadItem: {
              file,
              clearable: props.clearable,
              disabled: props.disabled,
              showSize: props.showSize
            }
          }
        }, {
          default: () => [slots.item?.(slotProps) ?? _createVNode(VFileUploadItem, {
            "key": i,
            "onClick:remove": () => onClickRemove(i)
          }, slots)]
        });
      })])]);
    });
  }
});
//# sourceMappingURL=VFileUpload.mjs.map