import CardGiftcardOutlined from "@mui/icons-material/CardGiftcardOutlined";
import NumbersOutlined from "@mui/icons-material/NumbersOutlined";
import Avatar from "@mui/material/Avatar";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
import { useCallback, useMemo, useState } from "react";
import { useToast } from "@/shared/ui/ToastProvider.jsx";
import { grantPrettyId, grantResource, listResourceGrants, listResources, lookupGrantTarget } from "../api/business.js";
import { useExternalAuth } from "../auth/ExternalAuthProvider.jsx";
import { PrettyIdGrantDialog, ResourceGrantDialog } from "../components/GrantDialogs.jsx";
import { hasAnyExternalCapability, hasExternalCapability } from "../config/capabilities.js";
import { useExternalI18n } from "../i18n/ExternalI18nProvider.jsx";
import { externalUiError, translateExternalError } from "../i18n/errors.js";
import { ExternalPage, ExternalPageState, PagePagination, ResponsiveDataList, StatusChip } from "../shared/PageComponents.jsx";
import { usePagedResource } from "../shared/usePagedResource.js";

export default function GrantsPage() {
  const { session } = useExternalAuth();
  const { showToast } = useToast();
  const { t } = useExternalI18n();
  const [dialog, setDialog] = useState("");
  const [page, setPage] = useState(1);
  const [submitting, setSubmitting] = useState(false);
  const canList = hasExternalCapability(session, "privilege:list");
  const canGrant = hasAnyExternalCapability(session, ["privilege:grant", "user-title:grant", "room-background:grant"]);
  const canGrantPrettyId = hasExternalCapability(session, "pretty-id:grant");
  const loadResources = useCallback(() => canGrant ? listResources({ page: 1, page_size: 200, status: "active" }) : Promise.resolve({ items: [], page: 1, pageSize: 200, total: 0 }), [canGrant]);
  const loadGrants = useCallback(() => canList ? listResourceGrants({ page, page_size: 20 }) : Promise.resolve({ items: [], page: 1, pageSize: 20, total: 0 }), [canList, page]);
  const resourcesState = usePagedResource(loadResources);
  const grantsState = usePagedResource(loadGrants);

  const execute = async (request, successKey) => {
    setSubmitting(true);
    try {
      await request();
      showToast(t(successKey), "success");
      setDialog("");
      grantsState.reload();
    } catch (requestError) {
      showToast(translateExternalError(requestError, t, "grants.failed"), "error");
    } finally {
      setSubmitting(false);
    }
  };

  const resolveTarget = async (input) => {
    const target = await lookupGrantTarget(input);
    if (!target.id) {
      throw externalUiError("errors.grantTarget");
    }
    return target;
  };

  const submitResource = (form) => execute(async () => {
    const target = await resolveTarget(form.target);
    await grantResource({
      commandId: createCommandId("external-resource-grant"),
      durationMs: Number(form.durationDays) * 86400000,
      quantity: Number(form.quantity),
      reason: form.reason.trim(),
      resourceId: Number(form.resourceId),
      targetUserId: target.id
    });
  }, "grants.resourceGranted");

  const submitPrettyId = (form) => execute(async () => {
    const target = await resolveTarget(form.target);
    await grantPrettyId({
      display_user_id: form.prettyId,
      duration_ms: Number(form.durationDays) * 86400000,
      reason: form.reason.trim(),
      target_user_id: target.id
    });
  }, "grants.prettyIdGranted");

  const columns = useMemo(() => [
    { key: "target", label: t("grants.targetUser"), render: (item) => String(item.targetUserId || item.target_user_id || item.userId || item.user_id || "-") },
    { key: "resource", label: t("grants.resource"), render: (item) => String(item.resourceName || item.resource_name || item.resourceId || item.resource_id || item.subject || "-") },
    { key: "quantity", label: t("grants.quantity"), render: (item) => String(item.quantity ?? item.amount ?? "-") },
    { key: "status", label: t("common.status"), render: (item) => <StatusChip status={item.status} /> },
    { key: "reason", label: t("common.reason"), render: (item) => String(item.reason || "-") }
  ], [t]);

  return (
    <ExternalPage
      actions={<>{canGrant ? <Button disabled={resourcesState.loading} onClick={() => setDialog("resource")} startIcon={<CardGiftcardOutlined />} variant="contained">{t("grants.grantResource")}</Button> : null}{canGrantPrettyId ? <Button onClick={() => setDialog("pretty")} startIcon={<NumbersOutlined />} variant="outlined">{t("grants.grantPrettyId")}</Button> : null}</>}
      title={t("grants.title")}
    >
      {canGrant ? (
        <Box className="external-form-panel">
          <Typography fontWeight={700} gutterBottom>{t("grants.availableResources")}</Typography>
          <Stack direction="row" sx={{ flexWrap: "wrap", gap: 1 }}>
            {resourcesState.data.items.slice(0, 12).map((resource) => <Stack direction="row" key={resource.id} spacing={0.75} sx={{ alignItems: "center" }}><Avatar src={resource.coverUrl} sx={{ height: 28, width: 28 }} variant="rounded">R</Avatar><Typography variant="body2">{resource.name}</Typography></Stack>)}
            {!resourcesState.loading && !resourcesState.data.items.length ? <Typography color="text.secondary">{t("common.noData")}</Typography> : null}
          </Stack>
        </Box>
      ) : null}
      {canList ? <><ExternalPageState error={grantsState.error} loading={grantsState.loading} onRetry={grantsState.reload} />{!grantsState.loading && !grantsState.error ? <><ResponsiveDataList columns={columns} items={grantsState.data.items} rowKey={(item, index) => item.grantId || item.grant_id || index} /><PagePagination {...grantsState.data} onChange={setPage} /></> : null}</> : null}
      <ResourceGrantDialog loading={submitting} open={dialog === "resource"} resources={resourcesState.data.items} onClose={() => setDialog("")} onSubmit={submitResource} />
      <PrettyIdGrantDialog loading={submitting} open={dialog === "pretty"} onClose={() => setDialog("")} onSubmit={submitPrettyId} />
    </ExternalPage>
  );
}

function createCommandId(prefix) {
  return `${prefix}-${globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random().toString(16).slice(2)}`}`;
}
