/*
 This file is part of GNU Taler
 (C) 2022 Taler Systems S.A.

 GNU Taler is free software; you can redistribute it and/or modify it under the
 terms of the GNU General Public License as published by the Free Software
 Foundation; either version 3, or (at your option) any later version.

 GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

 You should have received a copy of the GNU General Public License along with
 GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
import { TranslatedString } from "@gnu-taler/taler-util";
import { css } from "@linaria/core";
import { ComponentChildren, h, VNode } from "preact";
// eslint-disable-next-line import/extensions
import CloseIcon from "../svg/close_24px.inline.svg";
import ErrorOutlineIcon from "../svg/error_outline_outlined_24px.inline.svg";
import InfoOutlinedIcon from "../svg/info_outlined_24px.inline.svg";
import ReportProblemOutlinedIcon from "../svg/report_problem_outlined_24px.inline.svg";
import SuccessOutlinedIcon from "../svg/success_outlined_24px.inline.svg";
import { IconButton } from "./Button.js";
import { darken, lighten } from "./colors/manipulation.js";
import { Paper } from "./Paper.js";
import { theme } from "./style.jsx";
import { Typography } from "./Typography.js";

const defaultIconMapping = {
  success: SuccessOutlinedIcon,
  warning: ReportProblemOutlinedIcon,
  error: ErrorOutlineIcon,
  info: InfoOutlinedIcon,
};

const baseStyle = css`
  background-color: transparent;
  display: flex;
  padding: 6px 16px;
`;

const colorVariant = {
  standard: css`
    color: var(--color-light-06);
    background-color: var(--color-background-light-09);
  `,
  outlined: css`
    color: var(--color-light-06);
    border-width: 1px;
    border-style: solid;
    border-color: var(--color-light);
  `,
  filled: css`
    color: "#fff";
    font-weight: ${theme.typography.fontWeightMedium};
    background-color: var(--color-main);
  `,
};

interface Props {
  title?: TranslatedString;
  variant?: "filled" | "outlined" | "standard";
  role?: string;
  onClose?: () => Promise<void>;
  // icon: VNode;
  severity?: "info" | "warning" | "success" | "error";
  children: ComponentChildren;
  icon?: boolean;
}

const getColor = theme.palette.mode === "light" ? darken : lighten;
const getBackgroundColor = theme.palette.mode === "light" ? lighten : darken;

function Icon({ svg }: { svg: VNode }): VNode {
  return (
    <div
      class={css`
        margin-right: 12px;
        padding: 7px 0px;
        display: flex;
        font-size: 22px;
        opacity: 0.9;
        fill: currentColor;
      `}
      dangerouslySetInnerHTML={{ __html: svg as any }}
    ></div>
  );
}

function Action({ children }: { children: ComponentChildren }): VNode {
  return (
    <div
      class={css`
        display: flex;
        align-items: flex-start;
        padding: 4px 0px 0px 16px;
        margin-left: auto;
        margin-right: -8px;
      `}
    >
      {children}
    </div>
  );
}

function Message({
  title,
  children,
}: {
  title?: TranslatedString;
  children: ComponentChildren;
}): VNode {
  return (
    <div
      class={css`
        padding: 8px 0px;
        width: calc(100% - 48px - 36px);
      `}
    >
      {title && (
        <Typography
          class={css`
            font-weight: ${theme.typography.fontWeightBold};
          `}
          gutterBottom
        >
          {title}
        </Typography>
      )}
      {children}
    </div>
  );
}

export function Alert({
  variant = "standard",
  severity = "success",
  title,
  children,
  icon,
  onClose,
  ...rest
}: Props): VNode {
  return (
    <Paper
      class={[
        theme.typography.body2,
        baseStyle,
        severity && colorVariant[variant],
      ].join(" ")}
      style={{
        "--color-light-06": getColor(theme.palette[severity].light, 0.6),
        "--color-background-light-09": getBackgroundColor(
          theme.palette[severity].light,
          0.9,
        ),
        "--color-main": theme.palette[severity].main,
        "--color-light": theme.palette[severity].light,
        // ...(style as any),
        textAlign: "left",
      }}
      elevation={1}
    >
      {icon != false ? <Icon svg={defaultIconMapping[severity]} /> : null}
      <Message title={title}>{children}</Message>
      {onClose && (
        <Action>
          <IconButton svg={CloseIcon} onClick={onClose} />
        </Action>
      )}
    </Paper>
  );
}
