"""A file upload component."""

from typing import Dict, List, Optional

from pynecone.components.component import EVENT_ARG, Component
from pynecone.components.forms.input import Input
from pynecone.components.layout.box import Box
from pynecone.event import EventChain
from pynecone.var import BaseVar, Var

upload_file = BaseVar(name="e => File(e)", type_=EventChain)


class Upload(Component):
    """A file upload component."""

    library = "react-dropzone"

    tag = "ReactDropzone"

    # The list of accepted file types.
    accept: Var[Optional[List[str]]]

    # Whether the dropzone is disabled.
    disabled: Var[bool]

    # The maximum number of files that can be uploaded.
    max_files: Var[int]

    # The maximum file size (bytes) that can be uploaded.
    max_size: Var[int]

    # The minimum file size (bytes) that can be uploaded.
    min_size: Var[int]

    # Whether to allow multiple files to be uploaded.
    multiple: Var[bool] = True  # type: ignore

    # Whether to disable click to upload.
    no_click: Var[bool]

    # Whether to disable drag and drop.
    no_drag: Var[bool]

    # Whether to disable using the space/enter keys to upload.
    no_keyboard: Var[bool]

    @classmethod
    def create(cls, *children, **props) -> Component:
        """Create an upload component.

        Args:
            children: The children of the component.
            props: The properties of the component.

        Returns:
            The upload component.
        """
        # The file input to use.
        upload = Input.create(type_="file")
        upload.special_props = {BaseVar(name="{...getInputProps()}", type_=None)}

        # The dropzone to use.
        zone = Box.create(upload, *children, **props)
        zone.special_props = {BaseVar(name="{...getRootProps()}", type_=None)}

        # Create the component.
        return super().create(zone, on_drop=upload_file)

    @classmethod
    def get_controlled_triggers(cls) -> Dict[str, Var]:
        """Get the event triggers that pass the component's value to the handler.

        Returns:
            A dict mapping the event trigger to the var that is passed to the handler.
        """
        return {
            "on_drop": EVENT_ARG,
        }

    def _render(self):
        out = super()._render()
        out.args = ("getRootProps", "getInputProps")
        return out