import {
  Activity,
  Bell,
  Bot,
  CheckCircle2,
  ChevronDown,
  ChevronRight,
  Download,
  FileText,
  Keyboard,
  LogOut,
  PlayCircle,
  RefreshCw,
  ShieldCheck,
  SlidersHorizontal,
  UserRound,
  type LucideIcon
} from "lucide-react";
import type { ReactNode } from "react";
import {
  MAP_COMPACT_RADIUS_CLASS_NAME,
  MAP_ICON_CELL_RADIUS_CLASS_NAME,
  MAP_MAJOR_PANEL_RADIUS_CLASS_NAME,
  MAP_READABLE_RADIUS_CLASS_NAME
} from "@/features/map/core";
import { cn } from "@/shared/ui/cn";
import {
  StatusBadge,
  StatusDot,
  StatusIcon as SemanticStatusIcon,
  type StatusTone
} from "@/shared/ui/status";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuRadioGroup,
  DropdownMenuRadioItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger
} from "@/shared/ui/dropdown-menu";
import type { WorkbenchAlert, WorkbenchScenario, WorkbenchUser } from "../types";
import {
  compactHeaderControlButtonClassName,
  compactHeaderTextClassName,
  headerControlButtonClassName,
  headerControlIconClassName
} from "./workbench-top-bar-styles";

const scenarioStatusLabels: Record<WorkbenchScenario["status"], string> = {
  active: "运行中",
  draft: "草案",
  review: "待复核"
};

const scenarioStatusTones = {
  active: "info",
  draft: "neutral",
  review: "warning"
} satisfies Record<WorkbenchScenario["status"], StatusTone>;

const menuSurfaceClassName = cn(
  MAP_MAJOR_PANEL_RADIUS_CLASS_NAME,
  "acrylic-panel border p-2 text-slate-900"
);
const menuReadableRowClassName =
  "surface-well focus:bg-blue-50 focus:text-slate-950";
export function ScenarioMenu({
  open,
  onOpenChange,
  scenarios,
  activeScenarioId,
  activeScenarioName,
  onSelectScenario,
  onPreviewScenario,
  onCompareScenario,
  onExportScenarioReport
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  scenarios: WorkbenchScenario[];
  activeScenarioId: string;
  activeScenarioName: string;
  onSelectScenario: (scenarioId: string) => void;
  onPreviewScenario: () => void;
  onCompareScenario: () => void;
  onExportScenarioReport: () => void;
}) {
  return (
    <DropdownMenu modal={false} open={open} onOpenChange={onOpenChange}>
      <DropdownMenuTrigger asChild>
        <button
          type="button"
          className={cn("group max-w-[220px] px-2", headerControlButtonClassName)}
          aria-label="切换模拟方案"
        >
          <span className={headerControlIconClassName}>
            <SlidersHorizontal size={14} aria-hidden="true" />
          </span>
          <span className={cn(compactHeaderTextClassName, "truncate")}>场景 · {activeScenarioName}</span>
          <ChevronDown size={14} className="hidden shrink-0 text-slate-400 transition group-hover:text-blue-600 group-data-[state=open]:rotate-180 group-data-[state=open]:text-blue-600 2xl:block" aria-hidden="true" />
        </button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end" className={cn("w-[340px]", menuSurfaceClassName)}>
        <MenuHeader title="场景控制" meta={`当前：${activeScenarioName}`} />
        <MenuSectionLabel>场景列表</MenuSectionLabel>
        <DropdownMenuRadioGroup
          value={activeScenarioId}
          onValueChange={(nextScenarioId) => {
            onSelectScenario(nextScenarioId);
            onOpenChange(false);
          }}
        >
          {scenarios.map((scenario) => (
            <DropdownMenuRadioItem
              key={scenario.id}
              value={scenario.id}
              className={cn(
                "my-0.5 items-start border border-transparent py-2 pr-2 transition data-[state=checked]:border-blue-100 data-[state=checked]:bg-blue-50/80",
                MAP_COMPACT_RADIUS_CLASS_NAME,
                menuReadableRowClassName
              )}
            >
              <span className="min-w-0 flex-1">
                <span className="flex items-center justify-between gap-2">
                  <span className="truncate font-semibold text-slate-900">{scenario.name}</span>
                  <StatusBadge tone={scenarioStatusTones[scenario.status]}>
                    {scenarioStatusLabels[scenario.status]}
                  </StatusBadge>
                </span>
                <span className="mt-1 block text-xs leading-5 text-slate-500">{scenario.description}</span>
              </span>
            </DropdownMenuRadioItem>
          ))}
        </DropdownMenuRadioGroup>
        <MenuSeparator />
        <MenuSectionLabel>场景命令</MenuSectionLabel>
        <MenuAction icon={PlayCircle} label="预览影响范围" description="打开模拟图层与影响区" tone="primary" onSelect={onPreviewScenario} />
        <MenuAction icon={SlidersHorizontal} label="比较候选方案" description="影响、阀门与保供风险差异" onSelect={onCompareScenario} />
        <MenuAction icon={FileText} label="导出场景报告" description="生成调度复核材料" onSelect={onExportScenarioReport} />
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

export function AlertMenu({
  open,
  onOpenChange,
  alerts,
  compact = false,
  conditionFeedVisible,
  onSelectAlert,
  onToggleConditionFeed,
  onAnalyzeAlertsWithAgent
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  alerts: WorkbenchAlert[];
  compact?: boolean;
  conditionFeedVisible: boolean;
  onSelectAlert: (alert: WorkbenchAlert) => void;
  onToggleConditionFeed: () => void;
  onAnalyzeAlertsWithAgent: () => void | Promise<void>;
}) {
  const hasAlerts = alerts.length > 0;
  const latestAlertTime = alerts[0]?.time;

  return (
    <DropdownMenu modal={false} open={open} onOpenChange={onOpenChange}>
      <DropdownMenuTrigger asChild>
        <button
          type="button"
          className={cn(
            "group relative px-2",
            headerControlButtonClassName,
            hasAlerts && !compact &&
              "status-tone-danger border-transparent bg-[color-mix(in_oklch,var(--status-soft),var(--status-border)_45%)] text-[var(--status-foreground)] [@media(hover:hover)]:hover:border-[var(--status-border)] [@media(hover:hover)]:hover:bg-[color-mix(in_oklch,var(--status-soft),var(--status-border)_75%)] [@media(hover:hover)]:hover:text-[var(--status-foreground)] data-[state=open]:border-transparent data-[state=open]:bg-[color-mix(in_oklch,var(--status-soft),var(--status-border)_75%)] data-[state=open]:text-[var(--status-foreground)]",
            compact && compactHeaderControlButtonClassName
          )}
          aria-label={`查看异常处置面板，当前 ${alerts.length} 条待复核工况`}
        >
          <span
            className={cn(
              headerControlIconClassName,
              hasAlerts ? "status-icon status-tone-danger" : "bg-transparent!"
            )}
          >
            <Bell size={14} aria-hidden="true" />
          </span>
          <span className={compact ? "sr-only" : compactHeaderTextClassName}>异常处置</span>
          {compact ? (
            <StatusBadge
              tone={hasAlerts ? "danger" : "neutral"}
              className={cn(
                "absolute right-0 top-0 min-h-4 min-w-4 justify-center px-1 py-0 leading-none",
                !hasAlerts && "border-transparent! bg-transparent!"
              )}
            >
              {alerts.length}
            </StatusBadge>
          ) : (
            <StatusBadge
              tone={hasAlerts ? "danger" : "neutral"}
              className={cn("leading-none", !hasAlerts && "border-transparent! bg-transparent!")}
            >
              {alerts.length}
            </StatusBadge>
          )}
        </button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end" sideOffset={8} className={cn("w-[min(392px,calc(100vw-24px))]", menuSurfaceClassName)}>
        <AlertQueueSummary
          count={alerts.length}
          latestAlertTime={latestAlertTime}
          conditionFeedVisible={conditionFeedVisible}
        />
        <MenuSectionLabel>待复核工况</MenuSectionLabel>
        <div className="scheduled-feed-scroll max-h-[min(52dvh,420px)] overflow-y-auto pr-1">
          {hasAlerts ? alerts.map((alert) => (
            <DropdownMenuItem
              key={alert.id}
              className={cn(
                "status-tone-danger group my-1 grid min-h-[72px] grid-cols-[minmax(0,1fr)_auto] items-center gap-3 border border-transparent px-2.5 py-2.5 transition-colors focus:border-[var(--status-border)]",
                MAP_COMPACT_RADIUS_CLASS_NAME,
                menuReadableRowClassName
              )}
              onSelect={() => onSelectAlert(alert)}
            >
              <span className="min-w-0">
                <span className="flex min-w-0 items-center gap-2">
                  <StatusDot tone="danger" size="md" />
                  <span className="min-w-0 flex-1 truncate text-sm font-semibold leading-5 text-slate-950">{alert.title}</span>
                  <span className="shrink-0 font-mono text-xs font-semibold leading-4 text-slate-400 tabular-nums">{alert.time}</span>
                </span>
                <span className="mt-1 block line-clamp-2 text-xs leading-5 text-slate-500">{alert.description}</span>
              </span>
              <span className={cn("status-tone-danger grid h-7 w-7 shrink-0 place-items-center bg-slate-50 text-slate-400 transition-colors group-focus:text-[var(--status-foreground)]", MAP_ICON_CELL_RADIUS_CLASS_NAME)} aria-hidden="true">
                <ChevronRight size={14} />
              </span>
            </DropdownMenuItem>
          )) : (
            <div className={cn("surface-reading my-1 grid min-h-[76px] place-items-center border border-dashed border-slate-200 px-3 py-3 text-center", MAP_COMPACT_RADIUS_CLASS_NAME)}>
              <div className="min-w-0">
                <SemanticStatusIcon tone="success" size="md" className="mx-auto">
                  <CheckCircle2 size={16} />
                </SemanticStatusIcon>
                <p className="mt-1 text-xs font-semibold text-slate-700">当前无待复核工况</p>
                <p className="mt-0.5 text-xs leading-4 text-slate-500">新的工况提醒会进入这里。</p>
              </div>
            </div>
          )}
        </div>
        <div className="mt-2 grid grid-cols-[minmax(0,1fr)_auto] gap-2 border-t border-slate-200/70 pt-2">
          <MenuPlainButton
            label={conditionFeedVisible ? "工况面板已打开" : "打开工况面板"}
            description="查看时间线与处置详情"
            disabled={conditionFeedVisible}
            onClick={() => {
              onToggleConditionFeed();
              onOpenChange(false);
            }}
          />
          <MenuPrimaryButton
            disabled={!hasAlerts}
            icon={Bot}
            label={hasAlerts ? "工况汇总" : "等待提醒"}
            onClick={() => {
              void onAnalyzeAlertsWithAgent();
              onOpenChange(false);
            }}
          />
        </div>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

export function UserMenu({
  open,
  onOpenChange,
  user,
  onRefreshTiles,
  onShowDataStatus,
  onShowShortcuts,
  onExportConfig
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  user: WorkbenchUser;
  onRefreshTiles: () => void;
  onShowDataStatus: () => void;
  onShowShortcuts: () => void;
  onExportConfig: () => void;
}) {
  return (
    <DropdownMenu modal={false} open={open} onOpenChange={onOpenChange}>
      <DropdownMenuTrigger asChild>
        <button
          type="button"
          className={cn(
            "group lg:h-8 lg:w-auto lg:justify-start lg:px-2",
            headerControlButtonClassName,
            compactHeaderControlButtonClassName
          )}
          aria-label="打开用户菜单"
        >
          <span className={headerControlIconClassName}>
            <UserRound size={14} aria-hidden="true" />
          </span>
          <span className={cn(compactHeaderTextClassName, "text-sm font-semibold")}>{user.name}</span>
          <ChevronDown size={14} className="hidden shrink-0 text-slate-400 transition group-hover:text-blue-600 group-data-[state=open]:rotate-180 group-data-[state=open]:text-blue-600 2xl:block" aria-hidden="true" />
        </button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end" className={cn("w-72", menuSurfaceClassName)}>
        <MenuHeader title={user.name} meta={user.role} icon={ShieldCheck} />
        <MenuSectionLabel>会话控制</MenuSectionLabel>
        <MenuAction icon={Activity} label="查看运行状态" description="检查数据源与运行健康度" onSelect={onShowDataStatus} />
        <MenuAction icon={RefreshCw} label="刷新地图瓦片" description="请求地图重新渲染业务图层" onSelect={onRefreshTiles} />
        <MenuAction icon={Download} label="导出审计配置" description="保存当前地图和工具状态" onSelect={onExportConfig} />
        <MenuAction icon={Keyboard} label="操作参考" description="查看绘制与测量操作提示" onSelect={onShowShortcuts} />
        <MenuSeparator />
        <DropdownMenuItem disabled className={cn("px-2 py-2 text-slate-400", MAP_COMPACT_RADIUS_CLASS_NAME)}>
          <LogOut size={15} aria-hidden="true" />
          退出登录
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

function AlertQueueSummary({
  count,
  latestAlertTime,
  conditionFeedVisible
}: {
  count: number;
  latestAlertTime?: string;
  conditionFeedVisible: boolean;
}) {
  const hasAlerts = count > 0;

  return (
    <div className={cn("surface-reading overflow-hidden px-3 py-3", MAP_READABLE_RADIUS_CLASS_NAME)}>
      <div className="flex items-start justify-between gap-3">
        <div className="flex min-w-0 items-start gap-2.5">
          <SemanticStatusIcon
            tone={hasAlerts ? "danger" : "success"}
            size="md"
            className={cn("h-8 w-8", MAP_ICON_CELL_RADIUS_CLASS_NAME)}
          >
            {hasAlerts ? <Bell size={16} /> : <CheckCircle2 size={16} />}
          </SemanticStatusIcon>
          <div className="min-w-0">
            <h2 className="truncate text-sm font-semibold leading-5 text-slate-950">异常处置</h2>
            <p className="mt-0.5 text-xs leading-5 text-slate-500">
              {hasAlerts ? `${count} 条需复核${latestAlertTime ? ` · 最近 ${latestAlertTime}` : ""}` : "当前无待复核工况"}
            </p>
          </div>
        </div>
        <StatusBadge tone={hasAlerts ? "danger" : "success"}>
          {hasAlerts ? "需复核" : "正常"}
        </StatusBadge>
      </div>
      <div className="mt-2 flex items-center gap-1.5 text-xs leading-4 text-slate-500">
        <StatusDot tone={conditionFeedVisible ? "info" : "neutral"} />
        <span className="truncate">{conditionFeedVisible ? "工况面板已显示，可查看详情。" : "点击条目可打开工况任务。"}</span>
      </div>
    </div>
  );
}

function MenuPlainButton({
  label,
  description,
  disabled = false,
  onClick
}: {
  label: string;
  description: string;
  disabled?: boolean;
  onClick: () => void;
}) {
  return (
    <button
      type="button"
      disabled={disabled}
      onClick={onClick}
      className={cn(
        "flex h-11 min-w-0 flex-col justify-center border px-3 text-left transition-colors disabled:cursor-default disabled:opacity-70",
        MAP_COMPACT_RADIUS_CLASS_NAME,
        disabled
          ? "border-slate-200 bg-slate-50 text-slate-500"
          : "border-slate-200 bg-white text-slate-800 hover:border-blue-100 hover:bg-blue-50/55 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-blue-100"
      )}
    >
      <span className="truncate text-xs font-semibold leading-4">{label}</span>
      <span className="truncate text-xs font-medium leading-4 text-slate-500">{description}</span>
    </button>
  );
}

function MenuPrimaryButton({
  icon: Icon,
  label,
  disabled = false,
  onClick
}: {
  icon: LucideIcon;
  label: string;
  disabled?: boolean;
  onClick: () => void | Promise<void>;
}) {
  return (
    <button
      type="button"
      disabled={disabled}
      onClick={onClick}
      className={cn(
        "inline-flex h-11 shrink-0 items-center justify-center gap-2 border px-3 text-xs font-semibold transition-colors disabled:cursor-not-allowed",
        MAP_COMPACT_RADIUS_CLASS_NAME,
        disabled
          ? "border-slate-200 bg-slate-50 text-slate-400"
          : "border-blue-200 bg-blue-600 text-white shadow-lg shadow-blue-600/20 hover:bg-blue-700 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-blue-200"
      )}
    >
      <Icon size={14} aria-hidden="true" />
      <span className="max-w-[92px] truncate">{label}</span>
    </button>
  );
}

function MenuHeader({
  title,
  meta,
  tone = "default",
  icon: Icon
}: {
  title: string;
  meta: string;
  tone?: "default" | "warning";
  icon?: LucideIcon;
}) {
  return (
    <div className={cn("surface-control flex items-center justify-between gap-3 border px-2 py-2", MAP_READABLE_RADIUS_CLASS_NAME)}>
      <div className="min-w-0">
        <div className="flex min-w-0 items-center gap-1.5">
          {Icon ? <Icon size={13} className="shrink-0 text-slate-500" aria-hidden="true" /> : null}
          <span className="truncate text-sm font-semibold text-slate-950">{title}</span>
        </div>
        <p className={cn("mt-0.5 truncate text-xs text-slate-500", tone === "warning" && "status-tone-danger text-[var(--status-foreground)]")}>{meta}</p>
      </div>
      {tone === "warning" ? <StatusDot tone="danger" size="md" /> : null}
    </div>
  );
}

function MenuSectionLabel({ children }: { children: ReactNode }) {
  return <DropdownMenuLabel className="px-2 pb-1 pt-2.5 text-xs font-semibold uppercase text-slate-500">{children}</DropdownMenuLabel>;
}

function MenuSeparator() {
  return <DropdownMenuSeparator className="my-2 bg-slate-200/70" />;
}

function MenuAction({
  icon: Icon,
  label,
  description,
  tone = "default",
  onSelect
}: {
  icon: LucideIcon;
  label: string;
  description: string;
  tone?: "default" | "primary" | "warning";
  onSelect: () => void;
}) {
  return (
    <DropdownMenuItem
      className={cn(
        "my-0.5 items-center border border-transparent px-2 py-2 transition",
        MAP_COMPACT_RADIUS_CLASS_NAME,
        menuReadableRowClassName
      )}
      onSelect={onSelect}
    >
      <span
        className={cn(
          "grid h-7 w-7 shrink-0 place-items-center border",
          MAP_ICON_CELL_RADIUS_CLASS_NAME,
          tone === "primary" && "border-blue-100 bg-blue-50 text-blue-700",
          tone === "warning" && "status-icon status-tone-warning",
          tone === "default" && "border-slate-100 bg-slate-50 text-slate-600"
        )}
      >
        <Icon size={15} aria-hidden="true" />
      </span>
      <span className="min-w-0">
        <span className="block text-sm font-semibold leading-5 text-slate-900">{label}</span>
        <span className="mt-0.5 block truncate text-xs text-slate-500">{description}</span>
      </span>
    </DropdownMenuItem>
  );
}
