import type { OnChangeFn, PaginationState } from "@edr/ui-common";
import { Stack, Group, Text, Card, SimpleGrid, Skeleton } from "@mantine/core";

import type { RuleEngineResourceConfig } from "@/pages/ruleEngine/config/resources";
import type { RuleEngineRecord } from "@/types/rule-engine";

import RuleEngineListFooter from "./RuleEngineListFooter";
import RuleEngineRecordActions from "./RuleEngineRecordActions";
import { cardInitials, resolveCardPresentation } from "./ruleEngineCardMeta";
import { formatCell } from "./ruleEngineFormat";

export interface RuleEngineCardGridProps {
  config: RuleEngineResourceConfig;
  rows: RuleEngineRecord[];
  status: "loading" | "error" | "success";
  emptyMessage: string;
  itemLabel: string;
  pagination: PaginationState;
  pageCount: number;
  totalCount: number;
  onPaginationChange: OnChangeFn<PaginationState>;
  onEdit?: (record: RuleEngineRecord) => void;
  onDelete?: (record: RuleEngineRecord) => void;
  readOnly?: boolean;
  onViewChain?: () => void;
  onSubmitRate?: (id: string) => void;
  onApproveRate?: (record: RuleEngineRecord) => void;
}

const extractLabel = (value: unknown): string => {
  if (!value || typeof value !== "object") {
    return String(value || "");
  }

  const obj = value as Record<string, unknown>;
  return (
    (typeof obj.label === "string" ? obj.label : null) ||
    (typeof obj.cargoTypeName === "string" ? obj.cargoTypeName : null) ||
    (typeof obj.serviceName === "string" ? obj.serviceName : null) ||
    (typeof obj.code === "string" ? obj.code : null) ||
    (typeof obj.name === "string" ? obj.name : null) ||
    (typeof obj.actionLabel === "string" ? obj.actionLabel : null) ||
    String(value)
  );
};

const getSmartValue = (record: RuleEngineRecord, key: string): unknown => {
  const value = record[key as keyof RuleEngineRecord];

  // If the value is already an object, use it directly
  if (value && typeof value === "object") {
    return value;
  }

  // If the key ends with "Id" and there's a corresponding non-Id key, use that
  if (typeof key === "string" && key.endsWith("Id")) {
    const relatedKey = key.slice(0, -2); // Remove "Id" suffix
    const relatedValue = record[relatedKey as keyof RuleEngineRecord];
    if (relatedValue && typeof relatedValue === "object") {
      return relatedValue;
    }
  }

  return value;
};

const RuleEngineCardGrid = ({
  config,
  rows,
  status,
  emptyMessage,
  itemLabel,
  pagination,
  pageCount,
  totalCount,
  onPaginationChange,
  onEdit,
  onDelete,
  onViewChain,
  onSubmitRate,
  onApproveRate,
  readOnly = false,
}: RuleEngineCardGridProps) => {
  const presentation = resolveCardPresentation(config);

  if (status === "error") {
    return (
      <Stack
        align="center"
        justify="center"
        p="xl"
        style={{ minHeight: "400px" }}
      >
        <Text size="lg" fw={600} c="red">
          Failed to load data
        </Text>
        <Text size="sm" c="dimmed">
          Please refresh the page or try again later.
        </Text>
      </Stack>
    );
  }

  if (status === "loading") {
    return (
      <Stack gap="md" p="md">
        <SimpleGrid cols={{ base: 1, sm: 2, md: 2, lg: 3 }} spacing="md">
          {Array.from({ length: 6 }).map((_, index) => (
            <Card key={index} p="lg">
              <Group gap="sm" mb="md">
                <Skeleton height={44} width={44} radius="md" />
                <Stack gap={6} style={{ flex: 1 }}>
                  <Skeleton height={14} width="70%" radius="sm" />
                  <Skeleton height={10} width="40%" radius="sm" />
                </Stack>
              </Group>
              <Skeleton height={12} radius="sm" mb={8} />
              <Skeleton height={12} width="80%" radius="sm" />
            </Card>
          ))}
        </SimpleGrid>
      </Stack>
    );
  }

  if (status === "success" && rows.length === 0) {
    return (
      <Stack
        align="center"
        justify="center"
        p="xl"
        style={{ minHeight: "400px" }}
      >
        <Text size="lg" fw={600}>
          {emptyMessage}
        </Text>
        <Text size="sm" c="dimmed">
          Try adjusting your search or add a new record.
        </Text>
      </Stack>
    );
  }

  const avatarBg = "var(--mantine-color-gray-1)";
  const avatarText = "var(--mantine-color-gray-7)";

  return (
    <Stack gap="md" p="md">
      <SimpleGrid cols={{ base: 1, sm: 2, md: 2, lg: 3 }} spacing="md">
        {rows.map((record) => {
          const titleValue = getSmartValue(record, presentation.titleKey);
          const title = extractLabel(titleValue);

          const subtitleValue = presentation.subtitleKey
            ? getSmartValue(record, presentation.subtitleKey)
            : null;
          const subtitle = subtitleValue ? extractLabel(subtitleValue) : "";

          const codeValue = presentation.codeKey
            ? getSmartValue(record, presentation.codeKey)
            : null;
          const code = codeValue ? extractLabel(codeValue) : "";

          const statusValue = presentation.statusKey
            ? record[presentation.statusKey]
            : undefined;

          return (
            <Card
              key={record.id}
              p="lg"
              style={{ display: "flex", flexDirection: "column" }}
            >
              <Group justify="space-between" align="flex-start" mb="md">
                <Group gap="sm" style={{ flex: 1, minWidth: 0 }}>
                  <div
                    style={{
                      display: "flex",
                      alignItems: "center",
                      justifyContent: "center",
                      width: "44px",
                      height: "44px",
                      borderRadius: "8px",
                      background: avatarBg,
                      fontSize: "16px",
                      fontWeight: 700,
                      color: avatarText,
                      flexShrink: 0,
                    }}
                  >
                    {cardInitials(title)}
                  </div>
                  <div style={{ minWidth: 0, flex: 1 }}>
                    <Text size="sm" fw={700} truncate title={title}>
                      {title}
                    </Text>
                    {code && (
                      <Text size="xs" c="dimmed" style={{ marginTop: "4px" }}>
                        {code}
                      </Text>
                    )}
                  </div>
                </Group>
                {presentation.statusKey && (
                  <div>{formatCell(statusValue, "activeBadge")}</div>
                )}
              </Group>

              {(subtitle || presentation.detailColumns.length > 0) && (
                <Stack gap="xs" mb="md" style={{ flex: 1 }}>
                  {subtitle && (
                    <Group gap="xs">
                      <Text size="xs" c="dimmed" fw={500}>
                        {presentation.subtitleKey === "stepOrder"
                          ? "Step"
                          : "Type"}
                        :
                      </Text>
                      <Text size="xs" fw={500}>
                        {subtitle}
                      </Text>
                    </Group>
                  )}
                  {presentation.detailColumns.map((col) => {
                    const displayValue = getSmartValue(record, col.accessorKey);
                    return (
                      <Group
                        key={col.id}
                        justify="space-between"
                        gap="xs"
                        align="flex-start"
                      >
                        <Text size="xs" c="dimmed" fw={500}>
                          {col.header}:
                        </Text>
                        <div style={{ textAlign: "right", flex: 1 }}>
                          {formatCell(displayValue, col.format)}
                        </div>
                      </Group>
                    );
                  })}
                </Stack>
              )}

              <Group
                justify="flex-end"
                gap="xs"
                pt="md"
                style={{ borderTop: "1px solid var(--mantine-color-gray-2)" }}
              >
                <RuleEngineRecordActions
                  record={record}
                  config={config}
                  layout="compact"
                  readOnly={readOnly}
                  onEdit={onEdit ?? (() => { })}
                  onDelete={onDelete ?? (() => { })}
                  onViewChain={onViewChain}
                  onSubmitRate={onSubmitRate}
                  onApproveRate={onApproveRate}
                />
              </Group>
            </Card>
          );
        })}
      </SimpleGrid>

      <RuleEngineListFooter
        pagination={pagination}
        pageCount={pageCount}
        totalCount={totalCount}
        itemLabel={itemLabel}
        onPaginationChange={onPaginationChange}
      />
    </Stack>
  );
};

export default RuleEngineCardGrid;
