import { useAuth } from "@/contexts/auth-context";
import {
  createTheme,
  MantineProvider as MantineProviderCore,
} from "@mantine/core";
import { DatesProvider } from "@mantine/dates";
import { useLingui } from "@lingui/react";
import type { AppLocale } from "@/lib/i18n";
import ColorSchemeProvider from "./color-scheme-provider";
import { useState, useEffect, useMemo } from "react";
import "dayjs/locale/es-mx";
import "dayjs/locale/de";
import "dayjs/locale/ja";

// Mantine calendars pull month/weekday names from dayjs, which needs its own
// locale code (es → es-mx) and the locale files imported above.
const DAYJS_LOCALE: Record<AppLocale, string> = {
  en: "en",
  es: "es-mx",
  de: "de",
  ja: "ja",
};

const commonInputStyles = {
  label: {
    padding: 5,
  },
  root: {
    margin: "0",
  },
};

const pressFeedbackCss = `
.flxn-press {
  transition: transform 120ms cubic-bezier(0.32, 0.72, 0, 1);
}
.flxn-press:active:not(:disabled):not([data-disabled]):not([data-loading]) {
  transform: scale(0.97);
}
@media (prefers-reduced-motion: reduce) {
  .flxn-press,
  .flxn-press:active {
    transition: none;
    transform: none;
  }
}
`;

const theme = createTheme({
  defaultRadius: "sm",
  respectReducedMotion: true,
  fontFamily: '"Inter", sans-serif',
  headings: { fontFamily: '"League Spartan", sans-serif' },
  activeClassName: "flxn-press",
  components: {
    TextInput: {
      styles: commonInputStyles,
    },
    DateTimePicker: {
      styles: commonInputStyles,
    },
    Input: {
      styles: commonInputStyles,
    },
    Select: {
      styles: commonInputStyles,
    },
    Autocomplete: {
      styles: commonInputStyles,
    },
    Card: {
      defaultProps: {
        shadow: "xs",
      },
    },
    Title: {
      styles: {
        root: {
          letterSpacing: "-0.01em",
        },
      },
    },
  },
});

const MantineProvider = ({ children }: { children: React.ReactNode }) => {
  const { metadata } = useAuth();
  const { i18n } = useLingui();
  const [isHydrated, setIsHydrated] = useState(false);

  useEffect(() => {
    setIsHydrated(true);
  }, []);

  const colorScheme = isHydrated ? metadata.colorScheme || "auto" : "auto";
  const primaryColor = isHydrated ? metadata.accentColor || "blue" : "blue";

  const themeWithPrimaryColor = useMemo(
    () => ({ ...theme, primaryColor }),
    [primaryColor]
  );

  return (
    <MantineProviderCore
      defaultColorScheme={colorScheme}
      theme={themeWithPrimaryColor}
    >
      <style href="flxn-press-feedback" precedence="medium">
        {pressFeedbackCss}
      </style>
      <DatesProvider
        settings={{
          locale: DAYJS_LOCALE[i18n.locale as AppLocale] ?? "en",
        }}
      >
        <ColorSchemeProvider>{children}</ColorSchemeProvider>
      </DatesProvider>
    </MantineProviderCore>
  );
};

export default MantineProvider;
