import { Box, Text, UnstyledButton, Flex, Stack } from "@mantine/core";
import { CaretRightIcon } from "@phosphor-icons/react";
import React, { ComponentType, useContext } from "react";
import { useLingui } from "@lingui/react/macro";
import { SlidePanelContext } from "./slide-panel-context";

interface SlidePanelFieldProps {
  key: string;
  value?: any;
  onChange?: (value: any) => void;
  Component: ComponentType<any>;
  title: string;
  label?: string;
  placeholder?: string;
  formatValue?: (value: any) => string | React.ReactNode;
  componentProps?: Record<string, any>;
  withAsterisk?: boolean;
  error?: string;
}

const SlidePanelField = ({
  value,
  onChange,
  Component,
  title,
  label,
  placeholder,
  withAsterisk = false,
  formatValue,
  componentProps,
  error,
}: SlidePanelFieldProps) => {
  const { t, i18n } = useLingui();
  const context = useContext(SlidePanelContext);

  if (!context) {
    throw new Error("SlidePanelField must be used within a SlidePanel");
  }

  const handleClick = () => {
    if (!onChange) return;

    context.openPanel({
      title,
      Component,
      value,
      onChange,
      componentProps,
    });
  };

  const displayValue = () => {
    if (formatValue && value != null) {
      return formatValue(value);
    }
    if (value != null) {
      if (value instanceof Date) {
        return value.toLocaleDateString(i18n.locale);
      }
      return String(value);
    }
    return placeholder ?? t`Select value`;
  };

  return (
    <Box>
      <UnstyledButton
        onClick={handleClick}
        p="sm"
        style={{
          width: "100%",
          border: error
            ? "1px solid var(--mantine-color-error)"
            : "1px solid var(--mantine-color-dimmed)",
          borderRadius: "var(--mantine-radius-md)",
          backgroundColor: "var(--mantine-color-body)",
          textAlign: "left",
        }}
      >
        <Flex justify="space-between" align="center">
          <Stack>
            <Text size="sm" fw={500}>
              {label}
              {withAsterisk && (
                <Text
                  span
                  size="sm"
                  c="var(--mantine-color-error)"
                  fw={500}
                  ml={4}
                >
                  *
                </Text>
              )}
            </Text>
            <Text size="sm" c="dimmed">
              {displayValue()}
            </Text>
          </Stack>
          <CaretRightIcon
            size={24}
            weight="thin"
            style={{ marginRight: "12px" }}
          />
        </Flex>
      </UnstyledButton>
      {error && (
        <Text size="xs" c="var(--mantine-color-error)" fw={500} ml={4} mt={4}>
          {error}
        </Text>
      )}
    </Box>
  );
};

export { SlidePanelField };
