"use client"

import {
  Group,
  Paper,
  Stack,
  Text,
  type GroupProps,
  type PaperProps,
  type StackProps,
} from "@mantine/core"
import {
  DataTable,
  type DataTableDefaultColumnProps,
  type DataTableProps,
} from "mantine-datatable"
import type { CSSProperties, PropsWithChildren, ReactNode } from "react"
import classes from "./PageSurface.module.css"

function mergeClassName(...classNames: Array<string | undefined>) {
  return classNames.filter(Boolean).join(" ")
}

export const settingModalClassNames = {
  content: classes.modalContent,
  header: classes.modalHeader,
  title: classes.modalTitle,
  body: classes.modalBody,
}

export const settingModalFormClassName = classes.modalForm
export const settingModalActionsClassName = classes.modalActions
export const settingModalMetaTextClassName = classes.modalMetaText
export const settingSurfaceClassNames = classes

type SettingTableViewportProps = PropsWithChildren<{
  maxHeight: number | string
  className?: string
  style?: CSSProperties
}>

export function SettingPage({
  className,
  ...props
}: PropsWithChildren<StackProps>) {
  return (
    <Stack
      w="100%"
      h="calc(100vh - 60px)"
      p="md"
      gap="md"
      className={mergeClassName(classes.page, className)}
      {...props}
    />
  )
}

export function SettingPanel({
  className,
  withBorder = true,
  radius = "sm",
  p = "md",
  shadow,
  ...props
}: PropsWithChildren<PaperProps>) {
  return (
    <Paper
      withBorder={withBorder}
      radius={radius}
      p={p}
      shadow={shadow}
      className={mergeClassName(classes.panel, className)}
      {...props}
    />
  )
}

export function SettingTableViewport({
  maxHeight,
  className,
  style,
  children,
}: SettingTableViewportProps) {
  return (
    <div
      style={{ maxHeight, ...style }}
      className={mergeClassName(classes.tableViewport, className)}>
      {children}
    </div>
  )
}

export function SettingFilterPanel({
  className,
  ...props
}: PropsWithChildren<PaperProps>) {
  return (
    <SettingPanel
      className={mergeClassName(classes.filterPanel, className)}
      {...props}
    />
  )
}

export function SettingContentPanel({
  className,
  ...props
}: PropsWithChildren<PaperProps>) {
  return (
    <SettingPanel
      className={mergeClassName(classes.contentPanel, className)}
      {...props}
    />
  )
}

type SettingSectionHeaderProps = GroupProps & {
  eyebrow?: string
  title: ReactNode
  description?: ReactNode
  actions?: ReactNode
}

export function SettingSectionHeader({
  eyebrow,
  title,
  description,
  actions,
  className,
  ...props
}: SettingSectionHeaderProps) {
  return (
    <Group
      justify="space-between"
      align="flex-start"
      gap="sm"
      wrap="wrap"
      className={mergeClassName(classes.sectionHeader, className)}
      {...props}>
      <Stack gap={2}>
        {eyebrow ? (
          <Text className={classes.sectionEyebrow}>{eyebrow}</Text>
        ) : null}
        <Text className={classes.sectionTitle}>{title}</Text>
        {description ? (
          <Text className={classes.sectionDescription}>{description}</Text>
        ) : null}
      </Stack>
      {actions}
    </Group>
  )
}

type SettingListHeaderProps = {
  title: ReactNode
  count?: ReactNode
  actions?: ReactNode
  className?: string
}

export function SettingListHeader({
  title,
  count,
  actions,
  className,
}: SettingListHeaderProps) {
  return (
    <Group
      justify="space-between"
      align="center"
      wrap="wrap"
      gap="sm"
      className={mergeClassName(classes.listHeader, className)}>
      <Group gap="xs">
        <Text className={classes.listHeaderTitle}>{title}</Text>
        {count !== undefined ? (
          <Text className={classes.listHeaderCount}>{count}</Text>
        ) : null}
      </Group>
      {actions}
    </Group>
  )
}

export function SettingHeaderActions({
  className,
  gap = "sm",
  ...props
}: PropsWithChildren<GroupProps>) {
  return (
    <Group
      gap={gap}
      wrap="wrap"
      className={mergeClassName(classes.headerActions, className)}
      {...props}
    />
  )
}

export function SettingFilterActions({
  className,
  gap = "sm",
  justify = "flex-end",
  mt = "md",
  ...props
}: PropsWithChildren<GroupProps>) {
  return (
    <Group
      justify={justify}
      gap={gap}
      wrap="wrap"
      mt={mt}
      className={mergeClassName(classes.filterActions, className)}
      {...props}
    />
  )
}

export function SettingFilterStack({
  className,
  gap = 12,
  ...props
}: PropsWithChildren<StackProps>) {
  return (
    <Stack
      gap={gap}
      className={mergeClassName(classes.filterStack, className)}
      {...props}
    />
  )
}

type SettingInlineFilterFieldProps = {
  label: ReactNode
  children: ReactNode
  className?: string
  labelClassName?: string
  controlClassName?: string
  labelWidth?: number | string
}

export function SettingInlineFilterField({
  label,
  children,
  className,
  labelClassName,
  controlClassName,
  labelWidth = 80,
}: SettingInlineFilterFieldProps) {
  const style = {
    "--setting-inline-filter-label-width":
      typeof labelWidth === "number" ? `${labelWidth}px` : labelWidth,
  } as CSSProperties

  return (
    <div
      style={style}
      className={mergeClassName(classes.filterField, className)}>
      <Text className={mergeClassName(classes.filterLabel, labelClassName)}>
        {label}
      </Text>
      <div className={mergeClassName(classes.filterControl, controlClassName)}>
        {children}
      </div>
    </div>
  )
}

const settingDataTableStyles = {
  header: {
    backgroundColor: "#F7F8FA",
    borderBottom: "1px solid #E5E6EB",
    color: "#4E5969",
    fontSize: "14px",
    fontWeight: 500,
  },
  root: {
    maxWidth: "100%",
    minWidth: 0,
    fontSize: "14px",
    color: "#1D2129",
    borderBottom: "1px solid #E5E6EB",
    borderRadius: 4,
    overflow: "hidden",
    boxSizing: "border-box",
    backgroundColor: "#FFFFFF",
  },
  table: {
    backgroundColor: "#FFFFFF",
  },
  footer: {
    backgroundColor: "#FFFFFF",
  },
  pagination: {
    padding: "12px 16px",
    borderTop: "1px solid #E5E6EB",
  },
} as const

const settingDataTableDefaultColumnProps: DataTableDefaultColumnProps<
  Record<string, unknown>
> = {
  titleStyle: {
    whiteSpace: "nowrap",
    fontWeight: 500,
  },
}

export function SettingDataTable<T = Record<string, unknown>>(
  props: DataTableProps<T>
) {
  const {
    styles,
    defaultColumnProps,
    withTableBorder,
    withRowBorders,
    striped,
    highlightOnHover,
    loaderBackgroundBlur,
    loadingText,
    noRecordsText,
    minHeight,
    maxHeight,
    height,
    page,
    onPageChange,
    totalRecords,
    recordsPerPage,
    recordsPerPageLabel,
    paginationText,
    scrollAreaProps,
    ...rest
  } = props

  const paginationProps =
    page !== undefined &&
    onPageChange !== undefined &&
    recordsPerPage !== undefined
      ? {
          page,
          onPageChange,
          totalRecords,
          recordsPerPage,
          loadingText: loadingText ?? "正在加载数据...",
          recordsPerPageLabel: recordsPerPageLabel ?? "每页条数",
          paginationText:
            paginationText ??
            (({
              from,
              to,
              totalRecords,
            }: {
              from: number
              to: number
              totalRecords: number
            }) => `显示 ${from}-${to} 条，共 ${totalRecords} 条记录`),
        }
      : {}

  const tableProps = {
    withTableBorder: withTableBorder ?? true,
    withRowBorders: withRowBorders ?? true,
    striped: striped ?? false,
    highlightOnHover: highlightOnHover ?? false,
    defaultColumnProps:
      defaultColumnProps ??
      (settingDataTableDefaultColumnProps as DataTableDefaultColumnProps<T>),
    loaderBackgroundBlur: loaderBackgroundBlur ?? 0,
    noRecordsText: noRecordsText ?? "暂无数据",
    minHeight: minHeight ?? 360,
    maxHeight,
    height: height ?? (maxHeight !== undefined ? "auto" : undefined),
    scrollAreaProps: {
      type: "auto",
      ...scrollAreaProps,
    },
    styles: styles
      ? { ...settingDataTableStyles, ...styles }
      : settingDataTableStyles,
    ...paginationProps,
    ...rest,
  } as DataTableProps<T>

  return <DataTable {...tableProps} />
}

export const settingTabsStyles = {
  list: {
    padding: 4,
    backgroundColor: "#F7F8FA",
    border: "1px solid #E5E6EB",
    borderRadius: 4,
    gap: 8,
  },
  tab: {
    minHeight: 32,
    borderRadius: 4,
    padding: "0 12px",
    fontSize: 14,
    fontWeight: 500,
    lineHeight: "20px",
  },
  tabLabel: {
    color: "inherit",
    fontSize: 14,
    lineHeight: "20px",
  },
  panel: {
    flex: 1,
    minHeight: 0,
    minWidth: 0,
    paddingTop: 16,
  },
} as const

export const settingTabsClassNames = {
  list: classes.settingTabsList,
  tab: classes.settingTabsTab,
  tabLabel: classes.settingTabsTabLabel,
  panel: classes.settingTabsPanel,
} as const
