import { useMemo, useState } from "react";
import { Link } from "react-router-dom";
import { formatSeconds } from "../../utils/formatDate";
import {
  Badge,
  Button,
  DataGrid,
  DataGridBody,
  DataGridCell,
  DataGridHeader,
  DataGridHeaderCell,
  DataGridRow,
  MessageBar,
  MessageBarBody,
  Spinner,
  Text,
  Tooltip,
  makeStyles,
  tokens,
} from "@fluentui/react-components";
import {
  ArrowClockwiseRegular,
  ArrowSyncRegular,
  PauseRegular,
  PlayRegular,
  StopRegular,
} from "@fluentui/react-icons";
import { useCommonSectionStyles } from "../../components/commonStyles";
import { useJailsPageStyles } from "./jailsPageStyles";
import { useJails } from "../../hooks/useJails";
import type { JailSummary } from "../../types/jail";

const useOverviewStyles = makeStyles({
  link: {
    textDecoration: "none",
  },
  jailName: {
    fontFamily: tokens.fontFamilyMonospace,
    fontSize: tokens.fontSizeBase200,
  },
  badgeCount: {
    marginLeft: tokens.spacingHorizontalXS,
  },
  statusActionGroup: {
    display: "flex",
    gap: tokens.spacingHorizontalS,
    alignItems: "center",
  },
});

export function JailOverviewSection(): React.JSX.Element {
  const pageStyles = useJailsPageStyles();
  const overviewStyles = useOverviewStyles();
  const sectionStyles = useCommonSectionStyles();
  const { jails, total, loading, error, refresh, startJail, stopJail, setIdle, reloadJail, reloadAll } = useJails();
  const [opError, setOpError] = useState<string | null>(null);

  const handle = (fn: () => Promise<void>): void => {
    setOpError(null);
    fn().catch((err: unknown) => {
      setOpError(err instanceof Error ? err.message : String(err));
    });
  };

  const jailColumns = useMemo(
    () => [
      {
        columnId: "name",
        renderHeaderCell: () => "Jail",
        renderCell: (j: JailSummary) => (
          <Link to={`/jails/${encodeURIComponent(j.name)}`} className={overviewStyles.link}>
            <Text className={overviewStyles.jailName}>{j.name}</Text>
          </Link>
        ),
        compare: (a: JailSummary, b: JailSummary) => a.name.localeCompare(b.name),
      },
      {
        columnId: "status",
        renderHeaderCell: () => "Status",
        renderCell: (j: JailSummary) => {
          if (!j.running) return <Badge appearance="filled" color="danger">stopped</Badge>;
          if (j.idle) return <Badge appearance="filled" color="warning">idle</Badge>;
          return <Badge appearance="filled" color="success">running</Badge>;
        },
        compare: (a: JailSummary, b: JailSummary) => {
          if (a.running !== b.running) return a.running ? -1 : 1;
          if (a.idle !== b.idle) return a.idle ? 1 : -1;
          return 0;
        },
      },
      {
        columnId: "backend",
        renderHeaderCell: () => "Backend",
        renderCell: (j: JailSummary) => <Text size={200}>{j.backend}</Text>,
        compare: (a: JailSummary, b: JailSummary) => a.backend.localeCompare(b.backend),
      },
      {
        columnId: "banned",
        renderHeaderCell: () => "Banned",
        renderCell: (j: JailSummary) => <Text size={200}>{j.status ? String(j.status.currently_banned) : "—"}</Text>,
        compare: (a: JailSummary, b: JailSummary) => (a.status?.currently_banned ?? 0) - (b.status?.currently_banned ?? 0),
      },
      {
        columnId: "failed",
        renderHeaderCell: () => "Failed",
        renderCell: (j: JailSummary) => <Text size={200}>{j.status ? String(j.status.currently_failed) : "—"}</Text>,
        compare: (a: JailSummary, b: JailSummary) => (a.status?.currently_failed ?? 0) - (b.status?.currently_failed ?? 0),
      },
      {
        columnId: "findTime",
        renderHeaderCell: () => "Find Time",
        renderCell: (j: JailSummary) => <Text size={200}>{formatSeconds(j.find_time)}</Text>,
        compare: (a: JailSummary, b: JailSummary) => a.find_time - b.find_time,
      },
      {
        columnId: "banTime",
        renderHeaderCell: () => "Ban Time",
        renderCell: (j: JailSummary) => <Text size={200}>{formatSeconds(j.ban_time)}</Text>,
        compare: (a: JailSummary, b: JailSummary) => a.ban_time - b.ban_time,
      },
      {
        columnId: "maxRetry",
        renderHeaderCell: () => "Max Retry",
        renderCell: (j: JailSummary) => <Text size={200}>{String(j.max_retry)}</Text>,
        compare: (a: JailSummary, b: JailSummary) => a.max_retry - b.max_retry,
      },
    ],
    [overviewStyles],
  );

  return (
    <div className={sectionStyles.section}>
      <div className={sectionStyles.sectionHeader}>
        <Text as="h2" size={500} weight="semibold">
          Jail Overview
          {total > 0 && (
            <Badge appearance="tint" className={overviewStyles.badgeCount}>
              {String(total)}
            </Badge>
          )}
        </Text>
        <div className={pageStyles.actionRow}>
          <Button
            size="small"
            appearance="subtle"
            icon={<ArrowSyncRegular />}
            onClick={() => { handle(reloadAll); }}
          >
            Reload All
          </Button>
          <Button size="small" appearance="subtle" icon={<ArrowClockwiseRegular />} onClick={refresh}>
            Refresh
          </Button>
        </div>
      </div>

      {opError && (
        <MessageBar intent="error">
          <MessageBarBody>{opError}</MessageBarBody>
        </MessageBar>
      )}
      {error && (
        <MessageBar intent="error">
          <MessageBarBody>Failed to load jails: {error}</MessageBarBody>
        </MessageBar>
      )}

      {loading && jails.length === 0 ? (
        <div className={pageStyles.centred}>
          <Spinner label="Loading jails…" />
        </div>
      ) : (
        <div className={pageStyles.tableWrapper}>
          <DataGrid items={jails} columns={jailColumns} getRowId={(j: JailSummary) => j.name} focusMode="composite">
            <DataGridHeader>
              <DataGridRow>
                {({ renderHeaderCell }) => <DataGridHeaderCell>{renderHeaderCell()}</DataGridHeaderCell>}
              </DataGridRow>
            </DataGridHeader>
            <DataGridBody<JailSummary>>
              {({ item }) => (
                <DataGridRow<JailSummary> key={item.name}>
                  {({ renderCell, columnId }) => {
                    if (columnId === "status") {
                      return (
                        <DataGridCell>
                          <div className={overviewStyles.statusActionGroup}>
                            {renderCell(item)}
                            <Tooltip content={item.running ? "Stop jail" : "Start jail"} relationship="label">
                              <Button
                                size="small"
                                appearance="subtle"
                                icon={item.running ? <StopRegular /> : <PlayRegular />}
                                onClick={() => {
                                  handle(async () => {
                                    if (item.running) await stopJail(item.name);
                                    else await startJail(item.name);
                                  });
                                }}
                                aria-label={item.running ? `Stop ${item.name}` : `Start ${item.name}`}
                              />
                            </Tooltip>
                            <Tooltip content={item.idle ? "Resume from idle" : "Set idle"} relationship="label">
                              <Button
                                size="small"
                                appearance="subtle"
                                icon={<PauseRegular />}
                                onClick={() => { handle(async () => setIdle(item.name, !item.idle)); }}
                                disabled={!item.running}
                                aria-label={`Toggle idle for ${item.name}`}
                              />
                            </Tooltip>
                            <Tooltip content="Reload jail" relationship="label">
                              <Button
                                size="small"
                                appearance="subtle"
                                icon={<ArrowSyncRegular />}
                                onClick={() => { handle(async () => reloadJail(item.name)); }}
                                aria-label={`Reload ${item.name}`}
                              />
                            </Tooltip>
                          </div>
                        </DataGridCell>
                      );
                    }
                    return <DataGridCell>{renderCell(item)}</DataGridCell>;
                  }}
                </DataGridRow>
              )}
            </DataGridBody>
          </DataGrid>
        </div>
      )}
    </div>
  );
}
