/*!
 * Copyright (c) 2022-present, Okta, Inc. and/or its affiliates. All rights reserved.
 * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
 *
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and limitations under the License.
 */

import styled from "@emotion/styled";
import { memo, useCallback, useEffect, useRef, useState } from "react";
import { Button } from "../Buttons/Button.js";
import { Field } from "../Field.js";
import { useTranslation } from "../i18n.generated/i18n.js";
import { UploadIcon } from "../icons.generated/index.js";
import { useOdysseyDesignTokens } from "../OdysseyDesignTokensContext.js";
import { Support } from "../Typography.js";
import { FileUploadIllustration } from "./FileUploadIllustration.js";
import { FileUploadPreview } from "./FileUploadPreview.js";
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
export const fileUploadTypes = ["single", "multiple"];
export const fileUploadVariants = ["button", "dragAndDrop", "dragAndDropWithIcon"];
const BaseInputWrapper = styled.div({
  position: "relative",
  alignSelf: "flex-start",
  input: {
    position: "absolute",
    width: "100%",
    height: "100%",
    opacity: 0
  }
});
const InputContainer = styled(BaseInputWrapper)({
  display: "flex",
  alignSelf: "unset",
  alignItems: "center",
  justifyContent: "center",
  "&:has(input:focus)": {
    borderStyle: "solid"
  }
}, ({
  hasError,
  odysseyDesignTokens
}) => ({
  padding: `${odysseyDesignTokens.Spacing6} ${odysseyDesignTokens.Spacing3}`,
  border: hasError ? `1px solid ${odysseyDesignTokens.PaletteDangerMain}` : `1px dashed ${odysseyDesignTokens.HueNeutral300}`,
  borderRadius: odysseyDesignTokens.BorderRadiusMain,
  transition: `border-color ${odysseyDesignTokens.TransitionTimingMain}, box-shadow ${odysseyDesignTokens.TransitionTimingMain}`,
  "&:hover": {
    borderColor: odysseyDesignTokens.HueNeutral700
  },
  "&:has(input:focus)": {
    borderColor: odysseyDesignTokens.FocusOutlineColorPrimary,
    boxShadow: `0 0 0 1px ${odysseyDesignTokens.FocusOutlineColorPrimary}`,
    outline: `${odysseyDesignTokens.FocusOutlineWidthMain} ${odysseyDesignTokens.FocusOutlineStyle} transparent`,
    outlineOffset: odysseyDesignTokens.FocusOutlineOffsetTight
  },
  "&:has(input:disabled)": {
    backgroundColor: odysseyDesignTokens.HueNeutral50,
    border: `1px solid ${odysseyDesignTokens.BorderColorDisabled}`,
    color: odysseyDesignTokens.TypographyColorDisabled,
    "&:hover": {
      borderColor: odysseyDesignTokens.BorderColorDisabled
    }
  }
}));
const ButtonAndInfoContainer = styled.div({
  display: "flex",
  flexDirection: "column",
  alignItems: "center",
  justifyContent: "center"
});
const CenterAlignedSupportText = styled.div({
  textAlign: "center"
});
const FileUploader = ({
  acceptedFileTypes,
  errorMessage,
  id,
  isDisabled = false,
  isFullWidth,
  isOptional,
  hint,
  HintLinkComponent,
  label,
  onChange,
  type,
  variant
}) => {
  const odysseyDesignTokens = useOdysseyDesignTokens();
  const {
    t
  } = useTranslation();
  const inputRef = useRef(null);
  const [filesToUpload, setFilesToUpload] = useState([]);
  useEffect(() => {
    onChange(filesToUpload);
  }, [filesToUpload, onChange]);
  const updateFilesToUpload = useCallback(event => {
    const {
      files
    } = event.target;
    if (files && files.length > 0) {
      const mergedFiles = type === "multiple" ? filesToUpload.concat(Array.from(files)) : Array.from(files).slice();
      setFilesToUpload(mergedFiles);
    }
    event.target.value = "";
  }, [type, filesToUpload]);
  const triggerFileInputClick = useCallback(() => {
    inputRef.current?.click();
  }, [inputRef]);
  const removeFileFromFilesToUploadList = useCallback(name => {
    const deletedFileFilteredOut = filesToUpload.filter(file => file.name !== name);
    setFilesToUpload(deletedFileFilteredOut);
  }, [filesToUpload]);
  const renderFileInput = useCallback(({
    ariaDescribedBy,
    errorMessageElementId,
    id,
    labelElementId
  }) => {
    const acceptedFileTypesAsString = acceptedFileTypes?.join(",");
    const Input = () => _jsx("input", {
      accept: acceptedFileTypesAsString,
      "aria-describedby": ariaDescribedBy,
      "aria-errormessage": errorMessageElementId,
      "aria-labelledby": labelElementId,
      disabled: isDisabled,
      id: id,
      multiple: type === "multiple",
      onChange: updateFilesToUpload,
      ref: inputRef,
      title: "",
      type: "file"
    });
    if (variant === "button") {
      return _jsx(_Fragment, {
        children: _jsxs(BaseInputWrapper, {
          children: [_jsx(Input, {}), _jsx(Button, {
            isDisabled: isDisabled,
            label: t("fileupload.button.text"),
            onClick: triggerFileInputClick,
            startIcon: _jsx(UploadIcon, {}),
            variant: "secondary"
          })]
        })
      });
    }
    return _jsx(_Fragment, {
      children: _jsxs(InputContainer, {
        hasError: Boolean(errorMessage),
        odysseyDesignTokens: odysseyDesignTokens,
        children: [_jsx(Input, {}), _jsxs(ButtonAndInfoContainer, {
          children: [variant === "dragAndDropWithIcon" && _jsx(FileUploadIllustration, {}), _jsx(CenterAlignedSupportText, {
            children: _jsx(Support, {
              color: "textSecondary",
              children: t("fileupload.prompt.text")
            })
          }), _jsx(Button, {
            isDisabled: isDisabled,
            label: t("fileupload.button.text"),
            onClick: triggerFileInputClick,
            startIcon: _jsx(UploadIcon, {}),
            variant: "secondary"
          })]
        })]
      })
    });
  }, [acceptedFileTypes, errorMessage, isDisabled, inputRef, odysseyDesignTokens, triggerFileInputClick, t, type, updateFilesToUpload, variant]);
  return _jsxs(_Fragment, {
    children: [_jsx(Field, {
      errorMessage: errorMessage,
      fieldType: "single",
      hasVisibleLabel: true,
      hint: hint,
      HintLinkComponent: HintLinkComponent,
      id: id,
      isDisabled: isDisabled,
      isFullWidth: isFullWidth && variant !== "button",
      isOptional: isOptional,
      label: label,
      renderFieldComponent: renderFileInput
    }), filesToUpload.length > 0 && _jsx(FileUploadPreview, {
      fileNames: filesToUpload.map(file => file.name),
      isDisabled: isDisabled,
      onFileRemove: removeFileFromFilesToUploadList
    })]
  });
};
const MemoizedFileUploader = memo(FileUploader);
MemoizedFileUploader.displayName = "FileUploader";
export { MemoizedFileUploader as FileUpload, MemoizedFileUploader as FileUploader };
//# sourceMappingURL=FileUploader.js.map