"use client";

import React from "react";
import { AnimatePresence, motion } from "framer-motion";
import {
  Box,
  Button,
  Chip,
  CircularProgress,
  Collapse,
  IconButton,
  Stack,
  Typography,
  alpha,
  useTheme,
} from "@mui/material";
import type { Theme } from "@mui/material/styles";
import TerminalRounded from "@mui/icons-material/TerminalRounded";
import FolderOpenRounded from "@mui/icons-material/FolderOpenRounded";
import CheckCircleRounded from "@mui/icons-material/CheckCircleRounded";
import BlockRounded from "@mui/icons-material/BlockRounded";
import PushPinRounded from "@mui/icons-material/PushPinRounded";
import KeyboardArrowDownRounded from "@mui/icons-material/KeyboardArrowDownRounded";
import KeyboardArrowUpRounded from "@mui/icons-material/KeyboardArrowUpRounded";
import VerifiedUserRounded from "@mui/icons-material/VerifiedUserRounded";

import type { PermissionReply } from "@/lib/chatStream";
import type { Message } from "./GlobalChatbox.types";

const formatMetadataValue = (value: unknown) => {
  if (typeof value === "string") {
    return value;
  }
  try {
    return JSON.stringify(value);
  } catch {
    return "[unserializable]";
  }
};

const truncateText = (value: string, maxLength: number) =>
  value.length > maxLength ? `${value.slice(0, maxLength - 3)}...` : value;

const formatMetadata = (metadata: Record<string, unknown>) => {
  const entries = Object.entries(metadata)
    .filter(([key]) => !["command", "path", "file", "directory"].includes(key))
    .slice(0, 3);
  if (!entries.length) {
    return "";
  }
  return entries
    .map(([key, value]) => `${key}: ${truncateText(formatMetadataValue(value), 64)}`)
    .join("；");
};

const getPermissionTitle = (permission: NonNullable<Message["permissions"]>[number]) => {
  if (permission.permission === "external_directory") return "访问工作区外目录";
  if (permission.permission === "bash") return "执行终端命令";
  if (permission.permission === "edit") return "修改文件内容";
  return permission.permission || "工具权限请求";
};

const getPermissionPrimaryValue = (
  permission: NonNullable<Message["permissions"]>[number],
) => {
  const command = permission.metadata.command;
  if (typeof command === "string" && command.trim()) {
    return command.trim();
  }
  for (const key of ["path", "file", "directory"]) {
    const value = permission.metadata[key];
    if (typeof value === "string" && value.trim()) {
      return value.trim();
    }
  }
  return permission.patterns[0] ?? permission.permission;
};

const PermissionIcon = ({
  permission,
}: {
  permission: NonNullable<Message["permissions"]>[number];
}) => {
  if (permission.permission === "bash") {
    return <TerminalRounded sx={{ fontSize: 22 }} />;
  }
  if (permission.permission === "external_directory") {
    return <FolderOpenRounded sx={{ fontSize: 22 }} />;
  }
  return <VerifiedUserRounded sx={{ fontSize: 22 }} />;
};

const getPermissionStatusLabel = (status: NonNullable<Message["permissions"]>[number]["status"]) => {
  if (status === "approved_always") return "已始终允许";
  if (status === "approved_once") return "已允许一次";
  if (status === "rejected") return "已拒绝";
  if (status === "aborted") return "已中断";
  if (status === "error") return "提交失败";
  if (status === "submitting") return "提交中";
  return "等待确认";
};

const pendingPermissionColor = "#f9a825";
const approvedOncePermissionColor = "#00838f";

const getPermissionStatusColor = (
  status: NonNullable<Message["permissions"]>[number]["status"],
  theme: Theme,
) => {
  if (status === "approved_once") return approvedOncePermissionColor;
  if (status === "approved_always") return theme.palette.success.main;
  if (status === "rejected" || status === "error") return theme.palette.error.main;
  if (status === "aborted") return theme.palette.text.secondary;
  return pendingPermissionColor;
};

const getPermissionStatusTextColor = (
  status: NonNullable<Message["permissions"]>[number]["status"],
  theme: Theme,
) => {
  if (status === "approved_once") return "#006c78";
  if (status === "approved_always") return theme.palette.success.dark;
  if (status === "rejected" || status === "error") return theme.palette.error.main;
  if (status === "aborted") return theme.palette.text.secondary;
  return "#8a5a00";
};

const PermissionRequestCard = ({
  permission,
  isRunning,
  onReply,
}: {
  permission: NonNullable<Message["permissions"]>[number];
  isRunning: boolean;
  onReply: (requestId: string, reply: PermissionReply) => void;
}) => {
  const theme = useTheme();
  const isPending =
    isRunning && (permission.status === "pending" || permission.status === "error");
  const isSubmitting = isRunning && permission.status === "submitting";
  const primaryValue = getPermissionPrimaryValue(permission);
  const metadataText = formatMetadata(permission.metadata);
  const accentColor = getPermissionStatusColor(permission.status, theme);
  const statusTextColor = getPermissionStatusTextColor(permission.status, theme);
  const statusLabel = getPermissionStatusLabel(permission.status);

  return (
    <Box
      sx={{
        borderRadius: 3,
        overflow: "hidden",
        border: `1px solid ${alpha("#fff", 0.72)}`,
        bgcolor: alpha("#fff", 0.5),
        boxShadow: `0 8px 24px ${alpha("#000", 0.05)}`,
        backdropFilter: "blur(20px)",
        position: "relative",
        "&::before": {
          content: '""',
          position: "absolute",
          inset: "10px auto 10px 0",
          width: 3,
          borderRadius: "0 999px 999px 0",
          bgcolor: accentColor,
        },
      }}
    >
      <Stack
        direction="row"
        spacing={1}
        alignItems="center"
        sx={{
          px: 1.5,
          py: 1.25,
          pl: 1.75,
          borderBottom: `1px solid ${alpha("#000", 0.05)}`,
        }}
      >
        <Box
          sx={{
            width: 32,
            height: 32,
            borderRadius: "50%",
            display: "grid",
            placeItems: "center",
            flex: "0 0 auto",
            color: accentColor,
            bgcolor: alpha(accentColor, 0.1),
            border: `1px solid ${alpha(accentColor, 0.16)}`,
          }}
        >
          <PermissionIcon permission={permission} />
        </Box>
        <Box sx={{ minWidth: 0, flex: 1 }}>
          <Typography variant="subtitle2" fontWeight={800} noWrap sx={{ lineHeight: 1.25 }}>
            {getPermissionTitle(permission)}
          </Typography>
        </Box>
        <Chip
          size="small"
          label={statusLabel}
          sx={{
            height: 24,
            fontSize: "0.7rem",
            fontWeight: 800,
            borderRadius: "12px",
            bgcolor: alpha(accentColor, 0.12),
            color: statusTextColor,
            "& .MuiChip-label": { px: 1 },
          }}
        />
      </Stack>

      <Stack spacing={1.15} sx={{ px: 1.5, pt: 1.25, pb: 1.35, pl: 1.75 }}>
        <Box
          sx={{
            px: 1.25,
            py: 1,
            borderRadius: 2.5,
            bgcolor: alpha("#000", 0.025),
            border: `1px solid ${alpha("#000", 0.045)}`,
          }}
        >
          <Typography variant="caption" color="text.secondary" fontWeight={800}>
            请求目标
          </Typography>
          <Typography
            variant="body2"
            color="text.primary"
            fontFamily={permission.permission === "bash" ? "monospace" : undefined}
            sx={{
              mt: 0.25,
              lineHeight: 1.55,
              wordBreak: "break-word",
              whiteSpace: "pre-wrap",
            }}
          >
            {primaryValue}
          </Typography>
        </Box>

        {metadataText ? (
          <Typography variant="caption" color="text.secondary" sx={{ wordBreak: "break-word" }}>
            {metadataText}
          </Typography>
        ) : null}
      </Stack>

      {permission.error ? (
        <Box sx={{ px: 1.5, pb: isPending || isSubmitting ? 1 : 1.35, pl: 1.75 }}>
          <Typography
            variant="caption"
            color="error.main"
            sx={{
              display: "block",
              px: 1.25,
              py: 0.75,
              borderRadius: 2,
              bgcolor: alpha(theme.palette.error.main, 0.06),
              wordBreak: "break-word",
            }}
          >
            {permission.error}
          </Typography>
        </Box>
      ) : null}

      {isPending || isSubmitting ? (
        <Stack
          direction="row"
          spacing={1}
          flexWrap="wrap"
          useFlexGap
          sx={{ px: 1.5, pb: 1.35, pl: 1.75, pt: 0 }}
        >
            <Button
              size="small"
              variant="contained"
              disableElevation
              disabled={isSubmitting}
              onClick={() => onReply(permission.requestId, "once")}
              startIcon={
                isSubmitting ? (
                  <CircularProgress size={14} color="inherit" />
                ) : (
                  <CheckCircleRounded fontSize="small" />
                )
              }
              sx={{
                minWidth: 94,
                height: 34,
                borderRadius: "17px",
                bgcolor: "#00838f",
                fontWeight: 800,
                fontSize: "0.78rem",
                textTransform: "none",
                boxShadow: `0 4px 12px ${alpha("#00838f", 0.24)}`,
                "&:hover": {
                  bgcolor: "#006c78",
                  boxShadow: `0 6px 16px ${alpha("#00838f", 0.28)}`,
                },
              }}
            >
              允许一次
            </Button>
            <Button
              size="small"
              variant="outlined"
              disabled={isSubmitting}
              onClick={() => onReply(permission.requestId, "always")}
              startIcon={<PushPinRounded fontSize="small" />}
              sx={{
                height: 34,
                borderRadius: "17px",
                px: 1.5,
                fontWeight: 800,
                fontSize: "0.78rem",
                textTransform: "none",
                color: "#00838f",
                borderColor: alpha("#00838f", 0.24),
                bgcolor: alpha("#fff", 0.45),
                "&:hover": {
                  borderColor: alpha("#00838f", 0.36),
                  bgcolor: alpha("#00838f", 0.08),
                },
              }}
            >
              始终允许
            </Button>
            <Button
              size="small"
              color="error"
              variant="outlined"
              disabled={isSubmitting}
              onClick={() => onReply(permission.requestId, "reject")}
              startIcon={<BlockRounded fontSize="small" />}
              sx={{
                height: 34,
                borderRadius: "17px",
                px: 1.5,
                fontWeight: 800,
                fontSize: "0.78rem",
                textTransform: "none",
                borderColor: alpha(theme.palette.error.main, 0.22),
                bgcolor: alpha("#fff", 0.45),
                "&:hover": {
                  borderColor: alpha(theme.palette.error.main, 0.34),
                  bgcolor: alpha(theme.palette.error.main, 0.07),
                },
              }}
            >
              拒绝
            </Button>
        </Stack>
      ) : null}
    </Box>
  );
};

export const PermissionRequestGroup = ({
  permissions,
  isRunning,
  onReply,
}: {
  permissions: NonNullable<Message["permissions"]>;
  isRunning: boolean;
  onReply: (requestId: string, reply: PermissionReply) => void;
}) => {
  const theme = useTheme();
  const onceCount = permissions.filter((permission) => permission.status === "approved_once").length;
  const alwaysCount = permissions.filter((permission) => permission.status === "approved_always").length;
  const rejectedCount = permissions.filter((permission) => permission.status === "rejected").length;
  const abortedCount = permissions.filter((permission) => permission.status === "aborted").length;
  const pendingCount = permissions.filter(
    (permission) =>
      permission.status === "pending" ||
      permission.status === "submitting" ||
      permission.status === "error",
  ).length;
  const hasPendingPermissions = pendingCount > 0;
  const [expanded, setExpanded] = React.useState(false);
  const latestPermissions = permissions.slice(-3);
  const pendingPermissions = permissions.filter(
    (permission) =>
      permission.status === "pending" ||
      permission.status === "submitting" ||
      permission.status === "error",
  );
  const summaryItems = [
    { label: "共", value: permissions.length, color: theme.palette.text.secondary },
    { label: "允许一次", value: onceCount, color: getPermissionStatusColor("approved_once", theme), textColor: getPermissionStatusTextColor("approved_once", theme) },
    { label: "始终允许", value: alwaysCount, color: getPermissionStatusColor("approved_always", theme), textColor: getPermissionStatusTextColor("approved_always", theme) },
    { label: "拒绝", value: rejectedCount, color: getPermissionStatusColor("rejected", theme), textColor: getPermissionStatusTextColor("rejected", theme) },
    { label: "中断", value: abortedCount, color: getPermissionStatusColor("aborted", theme), textColor: getPermissionStatusTextColor("aborted", theme) },
  ];
  const chipColor =
    pendingCount > 0
      ? getPermissionStatusColor("pending", theme)
      : abortedCount > 0
        ? getPermissionStatusColor("aborted", theme)
        : rejectedCount > 0
          ? getPermissionStatusColor("rejected", theme)
          : getPermissionStatusColor("approved_always", theme);
  const chipTextColor =
    pendingCount > 0
      ? getPermissionStatusTextColor("pending", theme)
      : abortedCount > 0
        ? getPermissionStatusTextColor("aborted", theme)
        : rejectedCount > 0
          ? getPermissionStatusTextColor("rejected", theme)
          : getPermissionStatusTextColor("approved_always", theme);

  return (
    <Box
      sx={{
        borderRadius: 3,
        overflow: "hidden",
        border: `1px solid ${alpha("#fff", 0.72)}`,
        bgcolor: alpha("#fff", 0.46),
        boxShadow: `0 8px 24px ${alpha("#000", 0.045)}`,
        backdropFilter: "blur(20px)",
      }}
    >
      <Stack
        direction="row"
        alignItems="center"
        spacing={1}
        role="button"
        tabIndex={0}
        onClick={() => setExpanded((value) => !value)}
        onKeyDown={(event) => {
          if (event.key === "Enter" || event.key === " ") {
            event.preventDefault();
            setExpanded((value) => !value);
          }
        }}
        sx={{
          px: 1.5,
          py: 1.15,
          cursor: "pointer",
          transition: "background-color 0.2s ease",
          "&:hover": { bgcolor: alpha("#000", 0.025) },
        }}
      >
        <Box
          sx={{
            width: 30,
            height: 30,
            borderRadius: "50%",
            display: "grid",
            placeItems: "center",
            flex: "0 0 auto",
            color: chipColor,
            bgcolor: alpha(chipColor, 0.1),
            border: `1px solid ${alpha(chipColor, 0.15)}`,
          }}
        >
          <VerifiedUserRounded sx={{ fontSize: 18 }} />
        </Box>
        <Box sx={{ minWidth: 0, flex: 1 }}>
          <Typography variant="subtitle2" fontWeight={800} noWrap sx={{ lineHeight: 1.25 }}>
            权限请求
          </Typography>
          <Stack
            direction="row"
            flexWrap="wrap"
            gap={0.6}
            sx={{ mt: 0.55, maxHeight: 48, overflow: "hidden" }}
          >
            {summaryItems.map((item) => (
              <Box
                key={item.label}
                component="span"
                sx={{
                  display: "inline-flex",
                  alignItems: "center",
                  gap: 0.45,
                  height: 22,
                  px: 0.8,
                  borderRadius: "11px",
                  bgcolor: alpha(item.color, 0.08),
                  border: `1px solid ${alpha(item.color, 0.12)}`,
                  color: "textColor" in item ? item.textColor : item.color,
                  fontSize: "0.7rem",
                  fontWeight: 800,
                  lineHeight: 1,
                  whiteSpace: "nowrap",
                }}
              >
                <Box
                  component="span"
                  sx={{
                    color: "textColor" in item ? item.textColor : item.color,
                    fontWeight: 700,
                  }}
                >
                  {item.label}
                </Box>
                <Box component="span">{item.value} 项</Box>
              </Box>
            ))}
          </Stack>
        </Box>
        {isRunning && pendingCount > 0 ? (
          <Chip
            size="small"
            label={`待确认 ${pendingCount} 项`}
            sx={{
              height: 24,
              borderRadius: "12px",
              fontSize: "0.7rem",
              fontWeight: 800,
              color: chipTextColor,
              bgcolor: alpha(chipColor, 0.1),
              "& .MuiChip-label": { px: 1 },
            }}
          />
        ) : null}
        <IconButton
          size="small"
          aria-label={expanded ? "收起权限请求" : "展开权限请求"}
          sx={{
            width: 28,
            height: 28,
            color: "text.secondary",
            bgcolor: alpha("#000", 0.035),
            "&:hover": { bgcolor: alpha("#000", 0.07) },
          }}
        >
          {expanded ? (
            <KeyboardArrowUpRounded sx={{ fontSize: 18 }} />
          ) : (
            <KeyboardArrowDownRounded sx={{ fontSize: 18 }} />
          )}
        </IconButton>
      </Stack>

      {!expanded && isRunning && !hasPendingPermissions && latestPermissions.length > 0 ? (
        <Stack spacing={0} sx={{ px: 1.5, pb: 1.25 }}>
          {latestPermissions.map((permission, index) => {
            const primaryValue = getPermissionPrimaryValue(permission);
            const isLast = index === latestPermissions.length - 1;
            const itemColor = getPermissionStatusColor(permission.status, theme);
            const itemTextColor = getPermissionStatusTextColor(permission.status, theme);

            return (
              <Stack
                key={permission.requestId}
                direction="row"
                spacing={1}
                alignItems="center"
                sx={{
                  py: 0.8,
                  borderTop: index === 0 ? `1px solid ${alpha(chipColor, 0.1)}` : "none",
                  borderBottom: isLast ? "none" : `1px solid ${alpha("#000", 0.045)}`,
                }}
              >
                <Box
                  sx={{
                    width: 24,
                    height: 24,
                    borderRadius: "50%",
                    display: "grid",
                    placeItems: "center",
                    flex: "0 0 auto",
                    color: itemColor,
                    bgcolor: alpha(itemColor, 0.08),
                  }}
                >
                  <PermissionIcon permission={permission} />
                </Box>
                <Box sx={{ minWidth: 0, flex: 1 }}>
                  <Typography variant="caption" color="text.primary" fontWeight={750} noWrap sx={{ display: "block" }}>
                    {getPermissionTitle(permission)}
                  </Typography>
                  <Typography
                    variant="caption"
                    color="text.secondary"
                    noWrap
                    sx={{
                      display: "block",
                      fontFamily: permission.permission === "bash" ? "monospace" : undefined,
                    }}
                  >
                    {truncateText(primaryValue, 72)}
                  </Typography>
                </Box>
                <Chip
                  size="small"
                  label={getPermissionStatusLabel(permission.status)}
                  sx={{
                    height: 22,
                    borderRadius: "11px",
                    fontSize: "0.68rem",
                    fontWeight: 800,
                    color: itemTextColor,
                    bgcolor: alpha(itemColor, 0.08),
                    "& .MuiChip-label": { px: 0.85 },
                  }}
                />
              </Stack>
            );
          })}
        </Stack>
      ) : null}

      <AnimatePresence initial={false}>
        {!expanded && isRunning && hasPendingPermissions ? (
          <motion.div
            key="pending-permissions"
            initial={{ opacity: 0, y: -10, height: 0 }}
            animate={{ opacity: 1, y: 0, height: "auto" }}
            exit={{ opacity: 0, y: -8, height: 0 }}
            transition={{ duration: 0.2, ease: "easeOut" }}
            style={{ overflow: "hidden" }}
          >
            <Stack spacing={1} sx={{ px: 1.25, pb: 1.25 }}>
              {pendingPermissions.map((permission) => (
                <PermissionRequestCard
                  key={permission.requestId}
                  permission={permission}
                  isRunning={isRunning}
                  onReply={onReply}
                />
              ))}
            </Stack>
          </motion.div>
        ) : null}
      </AnimatePresence>

      <Collapse in={expanded} timeout="auto" unmountOnExit>
        <Stack spacing={1} sx={{ px: 1.25, pb: 1.25 }}>
          {permissions.map((permission) => (
            <PermissionRequestCard
              key={permission.requestId}
              permission={permission}
              isRunning={isRunning}
              onReply={onReply}
            />
          ))}
        </Stack>
      </Collapse>
    </Box>
  );
};
