import {
  Alert,
  AppShell,
  Avatar,
  Badge,
  Box,
  Button,
  Divider,
  FileInput,
  Group,
  Menu,
  Modal,
  NavLink,
  ScrollArea,
  Stack,
  Text,
  UnstyledButton,
  useMantineTheme,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import {
  Ban,
  ChevronDown,
  FileSignature,
  LogOut,
  Menu as MenuIcon,
  Plus,
  RefreshCw,
  // Search,
  Settings,
  Upload,
  User,
  X,
} from "lucide-react";
import { Fragment, type ReactNode, useState } from "react";
import { PROFILE_TYPE_LABELS } from "@/constants/profileMode";
import NotificationBellContainer from "@/features/notifications/NotificationBellContainer";
import SupportWidget from "@/features/support/SupportWidget";

export interface SidebarItem {
  label: string;
  href: string;
  icon?: ReactNode;
  children?: SidebarItem[];
  section?: string;
}

export interface AppLayoutProps {
  title?: string;
  sidebarItems: SidebarItem[];
  activeHref?: string;
  /**
   * Navigate to a route. Accepts an optional options object (e.g. `{ state }`)
   * forwarded to the router — used to pass navigation state like `fresh: true`
   * to the new-booking wizard. Compatible with react-router's `navigate`.
   */
  onNavigate?: (href: string, options?: { state?: unknown }) => void;
  userName?: string;
  userEmail?: string;
  /** Operational profiles for the company — surfaced as reference chips in the account menu. */
  companyProfiles?: {
    id?: string;
    type: string;
    reference: string;
    status?: string;
    reviewNote?: string | null;
  }[];
  /** Company type (e.g. "customer", "forwarder") — gates the "Add service" control. */
  companyType?: string | null;
  /**
   * Render the floating support-chat launcher. Defaults to true so the customer
   * portal is unaffected; shipping lines pass false — support chat is scoped to
   * a company, which they do not have.
   */
  showSupportWidget?: boolean;
  /** Create a new service profile of the given type (with business license). */
  onCreateProfile?: (
    type: ServiceType,
    licenseFiles: File[],
  ) => Promise<SwitchResult> | void;
  /** Resubmit a rejected service for approval, optionally replacing its license. */
  onReapplyProfile?: (
    profileId: string,
    licenseFiles: File[],
  ) => Promise<SwitchResult> | void;
  children: ReactNode;
}

/** Service profiles a customer company can operate under and switch between. */
type ServiceType = "importer" | "exporter" | "freight_forwarder";

/** Services a customer company can select in the header. */
const CUSTOMER_SERVICES: ServiceType[] = [
  "importer",
  "exporter",
  "freight_forwarder",
];
type SwitchResult =
  | { success: true; data?: unknown }
  | { success: false; error?: { message?: string } };

function getInitials(name: string): string {
  return name
    .split(" ")
    .filter(Boolean)
    .slice(0, 2)
    .map((n) => n[0].toUpperCase())
    .join("");
}

function getActivePage(
  items: SidebarItem[],
  activePath: string,
): { label: string } | null {
  const path = activePath.toLowerCase();

  // Longest match wins, for the same reason as the sidebar's isItemActive:
  // a nested href like "/shipping-line/bookings" must beat its "/shipping-line"
  // parent, which a first-match-wins scan would report as "Home".
  const best = items
    .flatMap((item) => [item, ...(item.children ?? [])])
    .filter(
      (item) =>
        path === item.href.toLowerCase() ||
        path.startsWith(item.href.toLowerCase() + "/"),
    )
    .sort((a, b) => b.href.length - a.href.length)[0];

  return best ? { label: best.label } : null;
}

const navClassNames = (active: boolean) => {
  if (active) {
    // Active tab gets the strong brand color: a green gradient pill, white
    // label + icon, and a soft lifted shadow so it clearly stands out from the
    // light rail around it.
    return {
      root: `rounded-[12px] font-medium transition-all duration-150 bg-gradient-to-r from-[#0EA371] to-[#0A8A60]! shadow-[0_6px_16px_rgba(14,163,113,0.30)]!`,
      label: `text-white! font-bold!`,
      section: `text-white!`,
    };
  }
  return {
    root: `rounded-[12px] font-medium transition-all duration-150 hover:bg-[#EBF4EF]!`,
    label: `text-edr-text! font-semibold! hover:text-[#0A6F4D]!`,
    section: `text-[#64748B]! hover:text-[#0A6F4D]!`,
  };
};

export function AppLayout({
  title = "EDR Freight",
  sidebarItems,
  activeHref = "",
  onNavigate,
  userName = "User",
  userEmail,
  companyProfiles = [],
  companyType,
  onCreateProfile,
  onReapplyProfile,
  showSupportWidget = true,
  children,
}: AppLayoutProps) {
  const [mobileOpen, { toggle: toggleMobile }] = useDisclosure();
  const theme = useMantineTheme();
  const borderColor = theme.colors["edr-border"][6];
  const mutedColor = theme.colors["edr-muted"][6];
  const textColor = theme.colors["edr-text"][6];
  const primaryColor = theme.colors["edr-green"][5];
  const primaryDarkColor = theme.colors["edr-green"][7];

  const activePath = activeHref.toLowerCase();
  const navigate = (href: string, options?: { state?: unknown }) =>
    onNavigate?.(href, options);

  const initials = getInitials(userName);
  const activePage = getActivePage(sidebarItems, activePath);

  // ── Add a service (customer companies only) ──
  // A customer can operate as importer, exporter and/or freight forwarder. The
  // header lets them ADD a service they don't have yet (creating a profile with
  // its business license). Data is no longer scoped by an "active" service —
  // every page shows all the company's data, with an optional per-page filter.
  const isCustomer = companyType === "customer";
  const profileExists = (type: ServiceType) =>
    companyProfiles.some((p) => p.type === type);
  const addableServices = CUSTOMER_SERVICES.filter((t) => !profileExists(t));
  // Rejected services can't be re-added (they exist), so they'd otherwise be
  // invisible here — surface them for resubmission alongside addable ones.
  const rejectedServices = isCustomer
    ? companyProfiles.filter(
        (p) =>
          p.status === "rejected" &&
          p.id &&
          CUSTOMER_SERVICES.includes(p.type as ServiceType),
      )
    : [];
  // Suspended services are also hidden by default (the profile exists) — surface
  // them so the customer can appeal by resubmitting a fresh business license.
  const suspendedServices = isCustomer
    ? companyProfiles.filter(
        (p) =>
          p.status === "suspended" &&
          p.id &&
          CUSTOMER_SERVICES.includes(p.type as ServiceType),
      )
    : [];
  const canManageServices =
    isCustomer &&
    (addableServices.length > 0 ||
      rejectedServices.length > 0 ||
      suspendedServices.length > 0);

  const [switching, setSwitching] = useState(false);
  const [createOpen, setCreateOpen] = useState(false);
  const [createTarget, setCreateTarget] = useState<ServiceType>("importer");
  // Non-null while resubmitting a rejected/suspended service; null while creating a new one.
  const [reapplyId, setReapplyId] = useState<string | null>(null);
  // Status of the profile being resubmitted ("rejected" | "suspended") — drives
  // the modal copy; null for a brand-new profile.
  const [reapplyStatus, setReapplyStatus] = useState<string | null>(null);
  // Reason the profile was suspended/rejected, surfaced in the modal.
  const [reapplyNote, setReapplyNote] = useState<string | null>(null);
  const [licenseFiles, setLicenseFiles] = useState<File[]>([]);
  const [createError, setCreateError] = useState<string | null>(null);

  const openServiceModal = (
    type: ServiceType,
    profile?: { id?: string; status?: string; reviewNote?: string | null },
  ) => {
    setCreateTarget(type);
    setReapplyId(profile?.id ?? null);
    setReapplyStatus(profile?.status ?? null);
    setReapplyNote(profile?.reviewNote ?? null);
    setLicenseFiles([]);
    setCreateError(null);
    setCreateOpen(true);
  };

  const handleAddService = (type: ServiceType) => openServiceModal(type);

  const handleCreateConfirm = async () => {
    const isReapply = reapplyId !== null;
    // A new profile needs its license up front; a resubmit may reuse the old one.
    if (!isReapply && licenseFiles.length === 0) {
      setCreateError("Please upload at least one business license file.");
      return;
    }
    setSwitching(true);
    setCreateError(null);
    try {
      const res = isReapply
        ? await onReapplyProfile?.(reapplyId, licenseFiles)
        : await onCreateProfile?.(createTarget, licenseFiles);
      if (res && !res.success) {
        setCreateError(res.error?.message ?? "Failed to submit service");
        return;
      }
      setCreateOpen(false);
      setReapplyId(null);
    } finally {
      setSwitching(false);
    }
  };

  const serviceLabel = (m: ServiceType) => PROFILE_TYPE_LABELS[m] ?? m;
  const isSuspendedAppeal = reapplyStatus === "suspended";

  // Longest matching href wins. A plain prefix test would light up every
  // ancestor: with a "/shipping-line" home item alongside "/shipping-line/
  // bookings", Home would stay highlighted on every page beneath it. Exact
  // matches still win outright, so customer routes are unaffected — their
  // sidebar hrefs are siblings, never nested inside one another.
  const bestMatchHref = sidebarItems
    .flatMap((item) => [item, ...(item.children ?? [])])
    .map((item) => item.href.toLowerCase())
    .filter((href) => activePath === href || activePath.startsWith(href + "/"))
    .sort((a, b) => b.length - a.length)[0];

  const isItemActive = (item: SidebarItem) =>
    bestMatchHref === item.href.toLowerCase();

  return (
    <AppShell
      layout="alt"
      navbar={{
        width: 260,
        breakpoint: "sm",
        collapsed: { mobile: !mobileOpen },
      }}
      header={{ height: 72 }}
      padding={0}
    >
      {/* ── Header (frosted glass; compact floating islands, mirrors the pen) ── */}
      <AppShell.Header
        withBorder={false}
        style={{
          // Solid white surface with a hairline base and a soft drop so it
          // floats above the content area.
          background: "#FFFFFF",
          borderBottom: `1px solid ${borderColor}`,
          boxShadow: "0 1px 12px rgba(16,24,40,0.04)",
        }}
      >
        <Group
          h="100%"
          px={24}
          pt={12}
          pb={8}
          justify="space-between"
          wrap="nowrap"
        >
          {/* Left: sidebar toggle + page title */}
          <Group gap={12} wrap="nowrap" align="center">
            <UnstyledButton
              onClick={toggleMobile}
              hiddenFrom="sm"
              aria-label="Toggle sidebar"
            >
              <MenuIcon size={18} color={textColor} strokeWidth={1.8} />
            </UnstyledButton>
            <Text
              style={{
                fontFamily: '"Inter", sans-serif',
                fontSize: 16,
                fontWeight: 700,
                color: textColor,
                lineHeight: 1,
              }}
            >
              {activePage ? activePage.label : title}
            </Text>
          </Group>

          {/* Right: switch + search + bell + avatar */}
          <Group gap={10} wrap="nowrap" align="center">
            {/* Add a service, or resubmit a rejected one (customer companies) */}
            {canManageServices && (
              <Menu
                width={240}
                position="bottom-end"
                withinPortal
                shadow="md"
                offset={8}
                radius="md"
              >
                <Menu.Target>
                  <Button
                    loading={switching}
                    variant="light"
                    color="edr-green"
                    radius={999}
                    size="sm"
                    leftSection={<Plus size={15} strokeWidth={1.8} />}
                    rightSection={<ChevronDown size={14} strokeWidth={1.8} />}
                    styles={{ root: { height: 36 } }}
                    visibleFrom="xs"
                  >
                    Add service
                  </Button>
                </Menu.Target>
                <Menu.Dropdown>
                  {addableServices.length > 0 && (
                    <>
                      <Menu.Label>Add a service</Menu.Label>
                      {addableServices.map((type) => (
                        <Menu.Item
                          key={type}
                          onClick={() => handleAddService(type)}
                          leftSection={<Plus size={15} strokeWidth={1.8} />}
                        >
                          {serviceLabel(type)}
                        </Menu.Item>
                      ))}
                    </>
                  )}
                  {rejectedServices.length > 0 && (
                    <>
                      {addableServices.length > 0 && <Menu.Divider />}
                      <Menu.Label>Rejected — resubmit</Menu.Label>
                      {rejectedServices.map((p) => (
                        <Menu.Item
                          key={p.id}
                          color="red"
                          onClick={() =>
                            openServiceModal(p.type as ServiceType, p)
                          }
                          leftSection={
                            <RefreshCw size={15} strokeWidth={1.8} />
                          }
                        >
                          {serviceLabel(p.type as ServiceType)}
                        </Menu.Item>
                      ))}
                    </>
                  )}
                  {suspendedServices.length > 0 && (
                    <>
                      {(addableServices.length > 0 ||
                        rejectedServices.length > 0) && <Menu.Divider />}
                      <Menu.Label>Suspended — appeal</Menu.Label>
                      {suspendedServices.map((p) => (
                        <Menu.Item
                          key={p.id}
                          color="orange"
                          onClick={() =>
                            openServiceModal(p.type as ServiceType, p)
                          }
                          leftSection={<Ban size={15} strokeWidth={1.8} />}
                          rightSection={
                            <Badge size="xs" color="orange" variant="light">
                              Suspended
                            </Badge>
                          }
                        >
                          {serviceLabel(p.type as ServiceType)}
                        </Menu.Item>
                      ))}
                    </>
                  )}
                </Menu.Dropdown>
              </Menu>
            )}

            {/* Search pill */}
            {/* <Group
              gap={8}
              align="center"
              visibleFrom="sm"
              style={{
                width: 260,
                height: 36,
                borderRadius: 999,
                border: `1px solid ${borderColor}`,
                backgroundColor: "#fff",
                padding: "0 14px",
                cursor: "text",
              }}
            >
              <Search size={15} color={mutedColor} strokeWidth={1.8} />
              <Text size="sm" style={{ color: mutedColor, userSelect: "none" }}>
                Search shipments, bookings…
              </Text>
            </Group> */}

            {/* Notifications */}
            <NotificationBellContainer />

            {/* Avatar pill */}
            <Menu
              width={220}
              position="bottom-end"
              withinPortal
              shadow="md"
              offset={8}
              radius="md"
            >
              <Menu.Target>
                <UnstyledButton
                  style={{
                    height: 36,
                    borderRadius: 999,
                    border: `1px solid ${borderColor}`,
                    backgroundColor: "#fff",
                    padding: "0 10px 0 4px",
                    display: "flex",
                    alignItems: "center",
                    gap: 7,
                    cursor: "pointer",
                  }}
                >
                  <Avatar radius="xl" size={28} color="edr-green.5">
                    <Text fw={700} fz={12} c="white">
                      {initials}
                    </Text>
                  </Avatar>
                  <ChevronDown size={15} color={mutedColor} strokeWidth={1.8} />
                </UnstyledButton>
              </Menu.Target>

              <Menu.Dropdown>
                <Box px="sm" py="xs">
                  <Text
                    size="sm"
                    fw={600}
                    truncate
                    style={{ color: textColor }}
                  >
                    {userName}
                  </Text>
                  {userEmail && (
                    <Text size="xs" c="dimmed" truncate>
                      {userEmail}
                    </Text>
                  )}
                </Box>
                {companyProfiles.length > 0 && (
                  <>
                    <Divider />
                    <Box px="sm" py="xs">
                      <Stack gap={6}>
                        {companyProfiles.map((p) => (
                          <Group
                            key={p.reference}
                            justify="space-between"
                            gap="sm"
                            wrap="nowrap"
                          >
                            <Text
                              size="xs"
                              fw={600}
                              style={{ color: textColor }}
                            >
                              {PROFILE_TYPE_LABELS[p.type] ?? p.type}
                            </Text>
                            <Text size="xs" ff="monospace" c="dimmed">
                              {p.reference}
                            </Text>
                          </Group>
                        ))}
                      </Stack>
                    </Box>
                  </>
                )}
                <Divider />
                <Menu.Item
                  leftSection={<FileSignature size={15} />}
                  onClick={() => navigate("/signature")}
                >
                  Signature &amp; Stamp
                </Menu.Item>
                <Menu.Item
                  leftSection={<User size={15} />}
                  onClick={() => navigate("/profile")}
                >
                  Profile
                </Menu.Item>
                <Menu.Item
                  leftSection={<Settings size={15} />}
                  onClick={() => navigate("/settings")}
                >
                  Settings
                </Menu.Item>
                <Divider />
                <Menu.Item
                  leftSection={<Plus size={15} />}
                  color="edr-green"
                  onClick={() =>
                    navigate("/bookings/new", { state: { fresh: true } })
                  }
                >
                  New Contract
                </Menu.Item>
                <Divider />
                <Menu.Item
                  leftSection={<LogOut size={15} />}
                  color="red"
                  onClick={() => navigate("/logout")}
                >
                  Logout
                </Menu.Item>
              </Menu.Dropdown>
            </Menu>
          </Group>
        </Group>
      </AppShell.Header>

      {/* ── Sidebar ── */}
      <AppShell.Navbar
        withBorder={false}
        style={{
          // Clean white rail.
          background: "#FFFFFF",
          borderRight: `1px solid ${borderColor}`,
          display: "flex",
          flexDirection: "column",
        }}
      >
        {/* Brand */}
        <Box
          style={{
            height: 60,
            flexShrink: 0,
            display: "flex",
            alignItems: "center",
            padding: "0 18px",
            justifyContent: "space-between",
          }}
        >
          <Group gap={11} wrap="nowrap">
            <img
              src="/assets/edr-logo.png"
              alt="EDR"
              style={{
                width: 40,
                height: 40,
                objectFit: "contain",
                flexShrink: 0,
              }}
            />
            <Box>
              <Text
                style={{
                  fontFamily: '"Inter", sans-serif',
                  fontWeight: 800,
                  fontSize: 19,
                  letterSpacing: "0.03em",
                  color: primaryColor,
                  lineHeight: 1.15,
                }}
              >
                EDR FREIGHT
              </Text>
              <Text
                style={{
                  fontSize: 10.5,
                  fontWeight: 500,
                  color: mutedColor,
                  lineHeight: 1.2,
                }}
              >
                Ethio–Djibouti Railway
              </Text>
            </Box>
          </Group>
          <UnstyledButton
            onClick={toggleMobile}
            hiddenFrom="sm"
            aria-label="Close sidebar"
          >
            <X size={18} color={mutedColor} strokeWidth={1.8} />
          </UnstyledButton>
        </Box>

        {/* Nav */}
        <ScrollArea flex={1} type="never" p="sm">
          <Stack gap={3}>
            {sidebarItems.map((item, i) => {
              const active = isItemActive(item);
              const hasChildren = !!item.children?.length;
              const childActive =
                item.children?.some((c) =>
                  activePath.startsWith(c.href.toLowerCase()),
                ) ?? false;

              const prevSection = sidebarItems[i - 1]?.section;
              const sectionLabel =
                item.section && item.section !== prevSection ? (
                  <Text
                    key={`section-${item.section}`}
                    tt="uppercase"
                    px="sm"
                    mt={i === 0 ? 6 : "lg"}
                    mb={6}
                    style={{
                      fontWeight: 700,
                      color: "#94A3B8",
                      fontSize: 10.5,
                      letterSpacing: "0.08em",
                    }}
                  >
                    {item.section}
                  </Text>
                ) : null;

              if (hasChildren) {
                return (
                  <Fragment key={item.href}>
                    {sectionLabel}
                    <NavLink
                      label={item.label}
                      leftSection={item.icon}
                      active={active || childActive}
                      defaultOpened={childActive}
                      classNames={navClassNames(active || childActive)}
                    >
                      {item.children!.map((child) => {
                        const cActive = activePath === child.href.toLowerCase();
                        return (
                          <NavLink
                            key={child.href}
                            label={child.label}
                            active={cActive}
                            onClick={() => navigate(child.href)}
                            classNames={navClassNames(cActive)}
                          />
                        );
                      })}
                    </NavLink>
                  </Fragment>
                );
              }

              return (
                <Fragment key={item.href}>
                  {sectionLabel}
                  <NavLink
                    label={item.label}
                    leftSection={item.icon}
                    active={active}
                    onClick={() => navigate(item.href)}
                    classNames={navClassNames(active)}
                  />
                </Fragment>
              );
            })}
          </Stack>
        </ScrollArea>

        {/* Promo card */}
        <Box style={{ padding: "0 12px 12px" }}>
          <Box
            style={{
              borderRadius: 16,
              overflow: "hidden",
              position: "relative",
              height: 260,
              marginBottom: 10,
            }}
          >
            {/* Train image fills the full card */}
            <img
              src="/assets/train-edr.jpg"
              alt=""
              style={{
                position: "absolute",
                bottom: "-16px",
                left: 0,
                right: "-70px",
                width: "120%",
                objectFit: "cover",
              }}
            />

            {/* Diagonal green overlay: lower-left → upper-right cut */}
            <Box
              style={{
                position: "absolute",
                inset: 0,
                top: "-75%",
                background:
                  "linear-gradient(165deg, #006149 40%, #0DC9A4 70%,  #0DC9A402 80%)",
                clipPath: "polygon(0 0, 100% 0, 100% 58%, 0 72%)",
              }}
            />

            {/* Text sits on top of the green overlay */}
            <Box
              style={{
                position: "relative",
                zIndex: 1,
                padding: "16px 16px 0",
              }}
              className="max-w-[180px]"
            >
              <Text
                style={{
                  fontSize: 15,
                  fontWeight: 800,
                  color: "#fff",
                  lineHeight: 1.3,
                  marginBottom: 4,
                }}
              >
                Moving Africa Forward
              </Text>
              <Text
                style={{
                  fontSize: 11,
                  color: "rgba(255,255,255,0.7)",
                  lineHeight: 1.5,
                }}
              >
                Reliable. Efficient. Connected.
              </Text>
            </Box>

            {/* Learn More — visible on the image area */}
            <Box
              style={{
                position: "absolute",
                bottom: 10,
                right: 10,
                zIndex: 2,
                display: "inline-flex",
                alignItems: "center",
                gap: 5,
                backgroundColor: "#fff",
                borderRadius: 8,
                padding: "6px 12px",
                cursor: "pointer",
              }}
            >
              <Text
                style={{
                  fontSize: 12,
                  fontWeight: 600,
                  color: primaryDarkColor,
                }}
              >
                Learn More
              </Text>
              <span style={{ fontSize: 12, color: primaryDarkColor }}>→</span>
            </Box>
          </Box>

          {/* Profile */}
          <Box
            style={{
              borderRadius: 12,
              border: `1px solid ${borderColor}`,
              padding: "10px",
              display: "flex",
              alignItems: "center",
              gap: 10,
              cursor: "pointer",
            }}
          >
            <Avatar
              radius="xl"
              size={38}
              color="edr-green.5"
              style={{ flexShrink: 0 }}
            >
              <Text fw={600} fz={13} c="white">
                {initials}
              </Text>
            </Avatar>
            <Box style={{ minWidth: 0, flex: 1 }}>
              <Text
                size="sm"
                fw={600}
                truncate
                style={{ color: textColor, lineHeight: 1.3 }}
              >
                {userName}
              </Text>
              {userEmail && (
                <Text
                  size="xs"
                  truncate
                  style={{ color: mutedColor, lineHeight: 1.3 }}
                >
                  {userEmail}
                </Text>
              )}
            </Box>
            <ChevronDown
              size={16}
              color={mutedColor}
              style={{ flexShrink: 0 }}
            />
          </Box>
        </Box>
      </AppShell.Navbar>

      {/* ── Main ── */}
      <AppShell.Main
        style={{
          backgroundColor: "##f8fafc",
          // Extra bottom clearance so the fixed support-chat FAB never
          // overlaps page content, even at the bottom of a scrolled page.
          paddingBottom: 112,
        }}
      >
        {children}
      </AppShell.Main>

      {/* Floating customer-support chat launcher. Hidden when the caller opts
          out: support chat resolves the user's external profile → company, and
          a shipping line has neither, so every poll would 403. */}
      {showSupportWidget && <SupportWidget />}

      {/* Create-profile modal — opens when switching to a mode the company
          doesn't have a profile for yet. */}
      <Modal
        opened={createOpen}
        onClose={() => (switching ? undefined : setCreateOpen(false))}
        title={
          isSuspendedAppeal
            ? `Appeal suspension — ${serviceLabel(createTarget)}`
            : reapplyId
              ? `Resubmit your ${serviceLabel(createTarget)} service`
              : `Set up your ${serviceLabel(createTarget)} profile`
        }
        centered
        radius="lg"
      >
        <Stack gap="md">
          <Text size="sm" c="dimmed">
            {isSuspendedAppeal
              ? `Your ${serviceLabel(
                  createTarget,
                ).toLowerCase()} service is currently suspended. Replace the business license if needed and resubmit — this sends your appeal back to EDR for review.`
              : reapplyId
                ? `Your ${serviceLabel(
                    createTarget,
                  ).toLowerCase()} service was rejected. Replace the business license if needed, then resubmit for approval.`
                : `You don't have a ${serviceLabel(
                    createTarget,
                  ).toLowerCase()} profile yet. Add your business license to create one — it goes to EDR for approval before you can operate under it.`}
          </Text>
          {isSuspendedAppeal && reapplyNote && (
            <Alert
              color="orange"
              variant="light"
              icon={<Ban size={16} />}
              title="Reason for suspension"
            >
              {reapplyNote}
            </Alert>
          )}
          <FileInput
            label={
              reapplyId ? "Business license (optional)" : "Business license"
            }
            multiple
            clearable
            accept="application/pdf,image/png,image/jpeg"
            leftSection={<Upload size={16} />}
            placeholder="Select license file(s)"
            value={licenseFiles}
            onChange={(files) => setLicenseFiles(files ?? [])}
            error={createError ?? undefined}
          />
          <Group justify="flex-end" gap="sm">
            <Button
              variant="default"
              onClick={() => setCreateOpen(false)}
              disabled={switching}
            >
              Cancel
            </Button>
            <Button
              color="edr-green"
              onClick={handleCreateConfirm}
              loading={switching}
            >
              {isSuspendedAppeal
                ? "Submit appeal"
                : reapplyId
                  ? "Resubmit"
                  : "Create"}
            </Button>
          </Group>
        </Stack>
      </Modal>
    </AppShell>
  );
}

export default AppLayout;
