/* Copyright 2026 Marimo. All rights reserved. */
import type { VariantProps } from "class-variance-authority";
import {
  DateField as AriaDateField,
  type DateFieldProps as AriaDateFieldProps,
  DateInput as AriaDateInput,
  type DateInputProps as AriaDateInputProps,
  DateSegment as AriaDateSegment,
  type DateSegmentProps as AriaDateSegmentProps,
  type DateValue as AriaDateValue,
  TimeField as AriaTimeField,
  type TimeFieldProps as AriaTimeFieldProps,
  type TimeValue as AriaTimeValue,
  type ValidationResult as AriaValidationResult,
  composeRenderProps,
  Text,
} from "react-aria-components";
import { cn } from "@/utils/cn";
import { FieldError, fieldGroupVariants, Label } from "./field";

const DateSegment = ({ className, ...props }: AriaDateSegmentProps) => {
  return (
    <AriaDateSegment
      className={composeRenderProps(className, (className) =>
        cn(
          "type-literal:px-0 inline rounded p-0.5 caret-transparent outline-solid outline-0",
          /* Placeholder */
          "data-placeholder:text-muted-foreground",
          /* Disabled */
          "data-disabled:cursor-not-allowed data-disabled:opacity-50",
          /* Focused */
          "data-focused:bg-accent data-focused:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
          /* Invalid */
          "data-invalid:data-focused:bg-destructive data-invalid:data-focused:data-placeholder:text-destructive-foreground data-invalid:data-focused:text-destructive-foreground data-invalid:data-placeholder:text-destructive data-invalid:text-destructive",
          className,
        ),
      )}
      {...props}
    />
  );
};

interface DateInputProps
  extends AriaDateInputProps, VariantProps<typeof fieldGroupVariants> {}

const DateInput = ({
  className,
  variant,
  ...props
}: Omit<DateInputProps, "children">) => {
  return (
    <AriaDateInput
      className={composeRenderProps(className, (className) =>
        cn(fieldGroupVariants({ variant }), "text-sm", className),
      )}
      {...props}
    >
      {(segment) => <DateSegment segment={segment} />}
    </AriaDateInput>
  );
};

interface DateFieldProps<
  T extends AriaDateValue,
> extends AriaDateFieldProps<T> {
  label?: string;
  description?: string;
  errorMessage?: string | ((validation: AriaValidationResult) => string);
}

const DateField = <T extends AriaDateValue>({
  label,
  description,
  className,
  errorMessage,
  ...props
}: DateFieldProps<T>) => {
  return (
    <AriaDateField
      className={composeRenderProps(className, (className) =>
        cn("group flex flex-col gap-2", className),
      )}
      {...props}
    >
      <Label>{label}</Label>
      <DateInput />
      {description && (
        <Text className="text-sm text-muted-foreground" slot="description">
          {description}
        </Text>
      )}
      <FieldError>{errorMessage}</FieldError>
    </AriaDateField>
  );
};

interface TimeFieldProps<
  T extends AriaTimeValue,
> extends AriaTimeFieldProps<T> {
  label?: string;
  description?: string;
  errorMessage?: string | ((validation: AriaValidationResult) => string);
}

const TimeField = <T extends AriaTimeValue>({
  label,
  description,
  errorMessage,
  className,
  ...props
}: TimeFieldProps<T>) => {
  return (
    <AriaTimeField
      className={composeRenderProps(className, (className) =>
        cn("group flex flex-col gap-2", className),
      )}
      {...props}
    >
      <Label>{label}</Label>
      <DateInput />
      {description && <Text slot="description">{description}</Text>}
      <FieldError>{errorMessage}</FieldError>
    </AriaTimeField>
  );
};

export { DateSegment, DateInput, DateField, TimeField };
export type { DateInputProps, DateFieldProps, TimeFieldProps };
