import React, { Fragment, useRef } from "react";
import { OSInfoCardItemProps, OSInfoCardProps } from "./props";
import { Menu } from "primereact/menu";
import { OSButton } from "../button";
import { OSLabel } from "../label";
import { OSAvatar } from "../avatar";
import { Skeleton } from "primereact/skeleton";
import Badge from "./Badge";
import Field from "./Field";
import { OSChip } from "../chip";

/**
 * Handle rendering of primary card with information and image.
 */
export function OSInfoCard({
    actions,
    loading,
    image,
    fallback,
    label,
    fancyLabel,
    heading,
    link,
    badge,
    fields,
    chips,
    avatarOptions,
    fieldOptions,
    className,
    labelOptions,
    ...props
}: OSInfoCardProps) {
    const dropDownRef = useRef<Menu>(null);

    return (
        <>
            <Menu
                model={actions ?? []}
                popup
                ref={dropDownRef}
                id="dropdown_user_options"
            />

            <div
                {...props}
                className={["os-info-card flex w-full h-min gap-2 rounded-3xl", className].join(" ")}
            >
                {/* Image */}
                <div className="flex relative h-min">
                    {loading ? (
                        <Skeleton height="8rem" width="8rem" shape="circle" />
                    ) : (
                        <OSAvatar
                            {...avatarOptions}
                            image={image}
                            zoomable
                            fallback={fallback}
                            size="large"
                            label={label}
                        />
                    )}
                    {badge && <Badge loading={loading} {...badge} />}
                </div>

                <div className="flex flex-col justify-center gap-1 flex-grow overflow-hidden">
                    {/** Heading */}
                    {heading
                        ? loading
                            ? <Skeleton height="1rem" width="25%" />
                            : React.isValidElement(heading)
                                ? heading
                                : <span
                                    className="os-info-card-heading w-min text-nowrap select-none"
                                    title={heading.toString()}>
                                    {heading}
                                </span>
                        : null}
                    <div>
                        {!loading ? (
                            <div
                                className="grid"
                                style={{
                                    gridTemplateRows: "100% 0px",
                                    gridTemplateColumns: "auto 0px 1fr",
                                }}
                            >
                                {/** Label */}
                                <div className="row-1 min-w-px">
                                    {" "}
                                    {/*This width determines float distance from text if enough space */}
                                    <OSLabel
                                        {...labelOptions}
                                        className={[
                                            labelOptions?.className,
                                            !(labelOptions?.link || labelOptions?.onClick || link) &&
                                            "select-all",
                                            actions && "pr-8",
                                        ].join(
                                            " "
                                        )} /** Space taken up by button (so text doesn't flow under it.) */
                                        label={fancyLabel || label || "Unknown"}
                                        tag={"h3"}
                                        link={link}
                                        truncate
                                    />
                                </div>
                                <div className="row-2 w-40" />
                                {/** Minimum distance between avatar and button */}
                                {/** Actions Menu */}
                                {actions && actions.length > 0 && (
                                    <div className="row-1 col-2 relative">
                                        <div className="absolute right-0 shrink-0">
                                            <OSButton
                                                className="os-info-card-action-button border-none"
                                                type="button"
                                                icon={{
                                                    identifier: "ellipsis-vertical",
                                                    colour: "black",
                                                }}
                                                onClick={(event) => dropDownRef.current?.toggle(event)}
                                            />
                                        </div>
                                    </div>
                                )}
                            </div>
                        ) : (
                            <Skeleton height="2rem" />
                        )}
                    </div>

                    {/* Fields */}
                    {
                        fields.filter(x => x !== false).map((field, index) => {
                            return <Fragment key={index}>
                                {React.isValidElement(field) ? (
                                    field
                                ) : (
                                    <Field
                                        {...fieldOptions}
                                        loading={loading}
                                        {...(field as OSInfoCardItemProps)}
                                    />
                                )}
                            </Fragment>
                        }) /** Draw info item per field */
                    }

                    {/** Tags */}
                    {chips && (
                        <div className="flex flex-wrap internal">
                            {
                                chips.map((tag, index) => (
                                    <OSChip loading={loading} {...tag} key={index} />
                                )) /** Draw tag item per tag */
                            }
                        </div>
                    )}
                </div>
            </div>
        </>
    );
}
