"use client";

import * as React from "react";
import { useParams, useRouter } from "next/navigation";
import { useSession } from "next-auth/react";
import Link from "next/link";
import equal from "fast-deep-equal";
import Image from "next/image";
import { useForm, Controller } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
import { toast } from "sonner";
import {
  ArrowLeft,
  Camera,
  Download,
  Eye,
  EyeOff,
  UserCog,
  Briefcase,
  Target,
  Users as UsersIcon,
  KeyRound,
} from "lucide-react";

import {
  useGetUserQuery,
  useGetRolesQuery,
  useUpdateUserMutation,
  useLazyGetBdrToAeHandoffPreviewQuery,
  useUploadAvatarMutation,
  useGetDealsQuery,
  useGetCustomersQuery,
  useGetPipelinesQuery,
} from "@/api/endpoints";
import type { ApiUser } from "@/api/users/types";
import { getApiEntityId, type Role as ApiRole } from "@/api/permissions/types";
import type { Deal } from "@/api/endpoints/deals-api";
import type { CustomerBackend } from "@/api/endpoints/customers-api";
import { resolveMediaDisplayUrl } from "@/api/client";
import { useAuthToken } from "@/hooks/use-auth-token";
import { useAbility } from "@/components/providers/ability-provider";
import { useAppDispatch, useAppSelector } from "@/store/hooks";
import { selectUserFromCache, setUserInCache } from "@/store";
import {
  isAccountExecutiveRoleName,
  isBdrRoleName,
} from "@/lib/permissions";
import { formatCurrencyCompact } from "@/lib/deal-display";
import {
  flattenPipelineStages,
  resolveLeadStageDisplayName,
} from "@/lib/deal-stage-labels";
import { toastUserMutationError } from "@/components/users/bdr-to-ae-handoff-dialog";
import { exportBdrAeLeadsToExcel } from "@/lib/export-bdr-ae-leads-xlsx";

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Loading } from "@/components/ui/loading";
import { NoDataFound } from "@/components/ui/no-data-found";
import { KPICard } from "@/components/ui/kpi-card";
import { ReactSelect } from "@/components/ui/react-select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { cn } from "@/lib/utils";
import {
  exportUserPortfolioTabToExcel,
  type PortfolioExportTab,
} from "@/lib/export-user-portfolio-xlsx";

const getFullImageUrl = (
  avatar: { id?: string; url?: string } | string | undefined,
) => resolveMediaDisplayUrl(avatar);

function getRoleId(role: ApiUser["role"]): string | undefined {
  if (!role) return undefined;
  return typeof role === "string" ? role : role.id;
}

function getRoleName(role: ApiUser["role"]): string {
  if (!role) return "—";
  return typeof role === "string" ? role : role.name;
}

function dealLabel(deal: Deal): string {
  return (
    deal.customerName?.trim() ||
    deal.companyName?.trim() ||
    deal.customer?.fullName?.trim() ||
    deal.customer?.companyName?.trim() ||
    "Unnamed"
  );
}

function toNumber(value: unknown): number {
  const n = typeof value === "string" ? parseFloat(value) : Number(value);
  return Number.isFinite(n) ? n : 0;
}

function formatDate(value?: string | null): string {
  if (!value) return "—";
  const d = new Date(value);
  if (Number.isNaN(d.getTime())) return "—";
  return d.toLocaleDateString(undefined, {
    year: "numeric",
    month: "short",
    day: "numeric",
  });
}

type PortfolioInvolvement = "owner" | "ae" | "bdr" | "contributor";

function formatPeopleList(
  people?: { id?: string; name?: string; email?: string | null }[],
): string {
  if (!people?.length) return "—";
  return people
    .map((p) => p.name?.trim() || p.email?.trim() || "—")
    .join(", ");
}

function mergeDealsById(...lists: Deal[][]): Deal[] {
  const map = new Map<string, Deal>();
  for (const list of lists) {
    for (const deal of list) {
      if (!map.has(deal.id)) map.set(deal.id, deal);
    }
  }
  return Array.from(map.values()).sort((a, b) => {
    const aTime = new Date(a.createdDate || a.createdAt).getTime();
    const bTime = new Date(b.createdDate || b.createdAt).getTime();
    return bTime - aTime;
  });
}

function getUserInvolvements(deal: Deal, userId: string): PortfolioInvolvement[] {
  const roles: PortfolioInvolvement[] = [];
  if (deal.ownerId === userId || deal.owner?.id === userId) roles.push("owner");
  if (
    deal.aeIds?.includes(userId) ||
    deal.aes?.some((person) => person.id === userId)
  ) {
    roles.push("ae");
  }
  if (
    deal.bdrIds?.includes(userId) ||
    deal.bdrs?.some((person) => person.id === userId)
  ) {
    roles.push("bdr");
  }
  if (deal.contributorIds?.includes(userId)) roles.push("contributor");
  return roles;
}

function involvementLabel(role: PortfolioInvolvement): string {
  switch (role) {
    case "owner":
      return "Owner";
    case "ae":
      return "AE";
    case "bdr":
      return "BDR";
    case "contributor":
      return "Contributor";
  }
}

function resolveCustomerAssignmentRole(
  customer: CustomerBackend,
  userId: string,
): string {
  const isOwner = customer.ownerId === userId;
  const isAm = customer.assignedAmId === userId;
  if (isOwner && isAm) return "Owner · AM";
  if (isOwner) return "Owner";
  if (isAm) return "Assigned AM";
  return "—";
}

const userEditSchema = yup.object({
  name: yup
    .string()
    .min(2, "Name must be at least 2 characters")
    .required("Name is required"),
  email: yup
    .string()
    .email("Invalid email address")
    .required("Email is required"),
  password: yup
    .string()
    .transform((v) => (v === "" ? undefined : v))
    .min(6, "Password must be at least 6 characters")
    .notRequired(),
  role: yup.string().notRequired(),
  file: yup.mixed().notRequired(),
});

type UserEditFormData = yup.InferType<typeof userEditSchema>;

const usersRoleSelectTriggerClassName = cn(
  "h-9 min-h-9 min-w-0 text-[13px] font-medium text-[#101828] font-['Lexend']",
  "rounded-[14px] border border-[#b9c7d0] bg-[#d1dbe1]",
  "shadow-[0px_2px_12px_rgba(15,23,42,0.07),inset_0_1px_0_rgba(255,255,255,0.55),0_0_0_2px_rgba(255,255,255,0.55)]",
  "pl-3.5 transition-[box-shadow,border-color]",
);

const usersRoleSelectContentClassName =
  "rounded-[14px] border border-white/80 bg-white/95 backdrop-blur-[15px] text-[#0a0a0a] shadow-[0px_2px_15px_0px_rgba(0,0,0,0.1)]";

const tabPanelCardClassName =
  "rounded-[20px] border border-[#eaecf0] overflow-hidden bg-white/70 backdrop-blur-md shadow-sm";

function InvolvementBadges({
  roles,
}: {
  roles: PortfolioInvolvement[];
}) {
  if (roles.length === 0) {
    return <span className="text-[13px] text-[#475467]">—</span>;
  }
  return (
    <div className="flex flex-wrap gap-1">
      {roles.map((role) => (
        <span
          key={role}
          className="inline-flex items-center px-2 py-0.5 rounded-full text-[10px] font-semibold bg-accent/10 text-accent border border-accent/20"
        >
          {involvementLabel(role)}
        </span>
      ))}
    </div>
  );
}

function UserPortfolioDealsTable({
  rows,
  userId,
  pipelineStages,
  highlightAe,
  highlightBdr,
  nameColumnLabel,
}: {
  rows: Deal[];
  userId: string;
  pipelineStages: ReturnType<typeof flattenPipelineStages>;
  highlightAe: boolean;
  highlightBdr: boolean;
  nameColumnLabel: string;
}) {
  return (
    <div className="overflow-x-auto scrollbar-themed">
      <Table variant="transparent">
        <TableHeader>
          <TableRow className="hover:bg-transparent border-b border-[#eaecf0] bg-[#f9fafb]/80">
            <TableHead className="font-bold text-[#475467] text-[11px] uppercase tracking-wider py-3.5">
              {nameColumnLabel}
            </TableHead>
            <TableHead className="font-bold text-[#475467] text-[11px] uppercase tracking-wider py-3.5">
              Your role
            </TableHead>
            <TableHead className="font-bold text-[#475467] text-[11px] uppercase tracking-wider py-3.5">
              Owner
            </TableHead>
            <TableHead
              className={cn(
                "font-bold text-[#475467] text-[11px] uppercase tracking-wider py-3.5",
                highlightAe && "text-accent",
              )}
            >
              AE{highlightAe ? " (pair)" : ""}
            </TableHead>
            <TableHead
              className={cn(
                "font-bold text-[#475467] text-[11px] uppercase tracking-wider py-3.5",
                highlightBdr && "text-accent",
              )}
            >
              BDR{highlightBdr ? " (pair)" : ""}
            </TableHead>
            <TableHead className="font-bold text-[#475467] text-[11px] uppercase tracking-wider py-3.5">
              Stage
            </TableHead>
            <TableHead className="font-bold text-[#475467] text-[11px] uppercase tracking-wider py-3.5">
              Created
            </TableHead>
          </TableRow>
        </TableHeader>
        <TableBody>
          {rows.map((row) => (
            <TableRow
              key={row.id}
              className="border-b border-[#eaecf0] hover:bg-[#f9fafb] transition-colors"
            >
              <TableCell className="py-3 font-semibold text-[13px]">
                <Link
                  href={`/leads/${row.id}`}
                  className="text-[#101828] hover:text-accent hover:underline"
                >
                  {dealLabel(row)}
                </Link>
              </TableCell>
              <TableCell className="py-3">
                <InvolvementBadges roles={getUserInvolvements(row, userId)} />
              </TableCell>
              <TableCell className="py-3 text-[13px] text-[#475467]">
                {row.owner?.name?.trim() || "—"}
              </TableCell>
              <TableCell
                className={cn(
                  "py-3 text-[13px]",
                  highlightAe
                    ? "font-medium text-[#101828]"
                    : "text-[#475467]",
                )}
              >
                {formatPeopleList(row.aes)}
              </TableCell>
              <TableCell
                className={cn(
                  "py-3 text-[13px]",
                  highlightBdr
                    ? "font-medium text-[#101828]"
                    : "text-[#475467]",
                )}
              >
                {formatPeopleList(row.bdrs)}
              </TableCell>
              <TableCell className="py-3">
                <span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-[11px] font-semibold bg-[#f2f4f7] text-[#344054] border border-[#d0d5dd]">
                  {resolveLeadStageDisplayName(row, pipelineStages)}
                </span>
              </TableCell>
              <TableCell className="py-3 text-[13px] text-[#475467]">
                {formatDate(row.createdDate || row.createdAt)}
              </TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </div>
  );
}

export default function UserEditPage() {
  const params = useParams();
  const router = useRouter();
  const ability = useAbility();
  const { token } = useAuthToken();
  const { status: sessionStatus } = useSession();
  const dispatch = useAppDispatch();
  const id = typeof params.id === "string" ? params.id : "";

  const canRead = ability.can("read", "user");
  const canViewPortfolio = ability.can("read", "user_portfolio");
  const canManageUser = ability.can("manage", "user");
  const canCreateUser = ability.can("create", "user");
  const canUpdateUser = ability.can("update", "user");
  const canEdit = canManageUser || canCreateUser || canUpdateUser;
  const sessionReady = sessionStatus !== "loading";
  const canFetchUser = sessionReady && !!token && !!id && canRead;

  const cachedUser = useAppSelector((state) => selectUserFromCache(state, id));

  const {
    data: latestUser,
    isPending: userPending,
    isFetching: userFetching,
    isError,
    error,
  } = useGetUserQuery(id, { skip: !canFetchUser });

  const user = latestUser ?? cachedUser;

  React.useEffect(() => {
    if (latestUser && !equal(cachedUser, latestUser)) {
      dispatch(setUserInCache(latestUser));
    }
  }, [latestUser, cachedUser, dispatch]);

  const userLoading =
    canFetchUser && !user && !isError && (userPending || userFetching);

  const { data: roles = [], isLoading: rolesLoading } = useGetRolesQuery(
    undefined,
    { skip: !token },
  );

  const { data: ownedLeads = [], isFetching: ownedLeadsFetching } =
    useGetDealsQuery(
      { userId: id, stageType: "Lead" },
      { skip: !token || !id || !canRead || !canViewPortfolio },
    );
  const { data: assignedLeads = [], isFetching: assignedLeadsFetching } =
    useGetDealsQuery(
      { contributorUserId: id, stageType: "Lead" },
      { skip: !token || !id || !canRead || !canViewPortfolio },
    );
  const { data: ownedDeals = [], isFetching: ownedDealsFetching } =
    useGetDealsQuery(
      { userId: id, stageType: "Deal" },
      { skip: !token || !id || !canRead || !canViewPortfolio },
    );
  const { data: assignedDeals = [], isFetching: assignedDealsFetching } =
    useGetDealsQuery(
      { contributorUserId: id, stageType: "Deal" },
      { skip: !token || !id || !canRead || !canViewPortfolio },
    );
  const { data: allCustomers = [], isFetching: customersFetching } =
    useGetCustomersQuery(undefined, {
      skip: !token || !id || !canRead || !canViewPortfolio,
    });
  const { data: pipelines = [] } = useGetPipelinesQuery(undefined, {
    skip: !token || !canRead || !canViewPortfolio,
  });

  const leads = React.useMemo(
    () => mergeDealsById(ownedLeads, assignedLeads),
    [ownedLeads, assignedLeads],
  );
  const deals = React.useMemo(
    () => mergeDealsById(ownedDeals, assignedDeals),
    [ownedDeals, assignedDeals],
  );
  const leadsFetching = ownedLeadsFetching || assignedLeadsFetching;
  const dealsFetching = ownedDealsFetching || assignedDealsFetching;

  const viewedUserRoleName = user ? getRoleName(user.role) : "—";
  const viewedUserIsAe = isAccountExecutiveRoleName(viewedUserRoleName);
  const viewedUserIsBdr = isBdrRoleName(viewedUserRoleName);

  const portfolioSummary = React.useMemo(() => {
    if (viewedUserIsAe) {
      return "Leads and deals include records this user owns or is assigned to as AE. BDR pairings are shown on each row.";
    }
    if (viewedUserIsBdr) {
      return "Leads and deals include records this user owns or is assigned to as BDR. AE pairings are shown on each row.";
    }
    return "Leads and deals include records this user owns or is assigned to as AE, BDR, or contributor.";
  }, [viewedUserIsAe, viewedUserIsBdr]);

  const pipelineStages = React.useMemo(
    () =>
      pipelines.flatMap((pipeline) =>
        pipeline.stages?.length ? flattenPipelineStages(pipeline.stages) : [],
      ),
    [pipelines],
  );

  const customers = React.useMemo(
    () =>
      allCustomers.filter(
        (c: CustomerBackend) => c.ownerId === id || c.assignedAmId === id,
      ),
    [allCustomers, id],
  );

  const [updateUser, { isLoading: updating }] = useUpdateUserMutation();
  const [uploadAvatar] = useUploadAvatarMutation();
  const [fetchHandoffPreview, { isFetching: bdrAeExportLoading }] =
    useLazyGetBdrToAeHandoffPreviewQuery();
  const [showPassword, setShowPassword] = React.useState(false);
  const [portfolioTab, setPortfolioTab] =
    React.useState<PortfolioExportTab>("leads");
  const [exportingPortfolio, setExportingPortfolio] = React.useState(false);

  const {
    control,
    handleSubmit,
    reset,
    setValue,
    watch,
    formState: { errors },
  } = useForm<UserEditFormData>({
    resolver: yupResolver(userEditSchema),
    defaultValues: { name: "", email: "", password: "", role: "" },
  });

  React.useEffect(() => {
    if (user) {
      reset({
        name: user.name,
        email: user.email,
        password: "",
        role: getRoleId(user.role) ?? "",
        file: undefined,
      });
    }
  }, [user, reset]);

  const selectedFile = watch("file");
  const [filePreview, setFilePreview] = React.useState<string | null>(null);

  React.useEffect(() => {
    if (selectedFile instanceof FileList && selectedFile.length > 0) {
      const reader = new FileReader();
      reader.onloadend = () => setFilePreview(reader.result as string);
      reader.readAsDataURL(selectedFile[0]);
    } else if (selectedFile instanceof File) {
      const reader = new FileReader();
      reader.onloadend = () => setFilePreview(reader.result as string);
      reader.readAsDataURL(selectedFile);
    } else {
      setFilePreview(null);
    }
  }, [selectedFile]);

  const roleSelectOptions = React.useMemo(
    () => [
      { value: "none", label: "No role" },
      ...roles.flatMap((r: ApiRole) => {
        const rid = getApiEntityId(r) ?? "";
        if (!rid) return [];
        return [{ value: rid, label: r.name }];
      }),
    ],
    [roles],
  );

  const dealsValue = React.useMemo(
    () => deals.reduce((sum, d) => sum + toNumber(d.budget), 0),
    [deals],
  );

  const resolveSelectedRoleName = React.useCallback(
    (roleId: string | undefined): string | undefined => {
      const rid = (roleId ?? "").trim();
      if (!rid || rid === "none") return undefined;
      const hit = roles.find((r: ApiRole) => getApiEntityId(r) === rid);
      return hit?.name;
    },
    [roles],
  );

  const isBdrToAeRoleChange = React.useCallback(
    (data: UserEditFormData) => {
      const currentRoleName = getRoleName(user?.role);
      const nextRoleName = resolveSelectedRoleName(data.role);
      return (
        isBdrRoleName(currentRoleName) &&
        isAccountExecutiveRoleName(nextRoleName)
      );
    },
    [user?.role, resolveSelectedRoleName],
  );

  const buildUserFormData = (data: UserEditFormData) => {
    const formData = new FormData();
    formData.append("name", data.name.trim());
    formData.append("email", data.email.trim().toLowerCase());
    if (data.password) formData.append("password", data.password);
    const normalizedRole = (data.role ?? "").trim();
    formData.append(
      "role",
      normalizedRole && normalizedRole !== "none" ? normalizedRole : "",
    );
    return formData;
  };

  const submitUserUpdate = async (
    data: UserEditFormData,
    options?: { silent?: boolean },
  ) => {
    if (!user) return;
    const fileObj =
      data.file instanceof FileList
        ? data.file[0]
        : data.file instanceof File
          ? data.file
          : undefined;

    if (fileObj && fileObj.size > 600 * 1024) {
      toast.error("Avatar image must be smaller than 600KB");
      return;
    }

    const formData = buildUserFormData(data);
    await updateUser({ id: user.id, body: formData }).unwrap();
    if (fileObj) {
      await uploadAvatar({ userId: user.id, file: fileObj }).unwrap();
    }
    if (!options?.silent) toast.success("User updated");
    setValue("password", "");
    setValue("file", undefined);
  };

  const hasNonRoleFormChanges = React.useCallback(
    (data: UserEditFormData, currentUser: ApiUser) => {
      if (data.name.trim() !== currentUser.name) return true;
      if (
        data.email.trim().toLowerCase() !==
        currentUser.email.trim().toLowerCase()
      ) {
        return true;
      }
      if (data.password?.trim()) return true;
      if (data.file) return true;
      return false;
    },
    [],
  );

  const onSubmit = handleSubmit(async (data) => {
    if (!user) return;

    if (isBdrToAeRoleChange(data)) {
      try {
        const preview = await fetchHandoffPreview(user.id).unwrap();
        await exportBdrAeLeadsToExcel(preview);

        const currentRoleId = getRoleId(user.role) ?? "";
        setValue("role", currentRoleId);

        const dataKeepingBdrRole = { ...data, role: currentRoleId };
        const leadLabel =
          preview.leadCount === 1 ? "1 lead" : `${preview.leadCount} leads`;

        if (hasNonRoleFormChanges(dataKeepingBdrRole, user)) {
          await submitUserUpdate(dataKeepingBdrRole, { silent: true });
          toast.success(
            preview.leadCount > 0
              ? `Role kept as BDR. AE assignments exported (${leadLabel}). Other changes saved.`
              : "Role kept as BDR. No assigned leads to export. Other changes saved.",
          );
        } else {
          toast.success(
            preview.leadCount > 0
              ? `Role not changed. AE assignments exported for ${leadLabel}.`
              : "Role not changed. This BDR has no assigned leads to export.",
          );
        }
      } catch (e: unknown) {
        toastUserMutationError(e, "Failed to export BDR lead AE assignments");
      }
      return;
    }

    try {
      await submitUserUpdate(data);
    } catch (e: unknown) {
      toastUserMutationError(e, "Failed to update user");
    }
  });

  const portfolioExportCount =
    portfolioTab === "leads"
      ? leads.length
      : portfolioTab === "deals"
        ? deals.length
        : customers.length;

  const handlePortfolioExport = React.useCallback(async () => {
    if (!user) return;
    if (portfolioExportCount === 0) {
      toast.error(`No ${portfolioTab} to export for this user.`);
      return;
    }

    const toastId = toast.loading("Generating Excel export…");
    setExportingPortfolio(true);
    try {
      await exportUserPortfolioTabToExcel({
        tab: portfolioTab,
        userId: id,
        userName: user.name,
        leads,
        deals,
        customers,
        pipelineStages,
      });
      toast.success("Excel ready — check your downloads", { id: toastId });
    } catch (err: unknown) {
      const message =
        err instanceof Error ? err.message : "Could not generate the Excel file.";
      toast.error(message, { id: toastId });
    } finally {
      setExportingPortfolio(false);
    }
  }, [
    user,
    portfolioExportCount,
    portfolioTab,
    id,
    leads,
    deals,
    customers,
    pipelineStages,
  ]);

  if (!token) {
    return (
      <div className="flex min-h-[40vh] items-center justify-center p-8">
        <Loading message="Loading…" />
      </div>
    );
  }

  if (!canRead) {
    if (!sessionReady) {
      return (
        <div className="flex min-h-[40vh] items-center justify-center p-8">
          <Loading message="Loading session…" />
        </div>
      );
    }
    return (
      <div className="mx-auto max-w-lg p-8">
        <NoDataFound
          message="Access denied"
          description="You do not have permission to view user details."
        />
        <div className="mt-6 flex justify-center">
          <Button variant="outline" asChild>
            <Link href="/users">Back to users</Link>
          </Button>
        </div>
      </div>
    );
  }

  return (
    <div className="relative flex flex-col h-full gap-6 p-4 sm:p-6 md:p-8 animate-in fade-in duration-500 overflow-y-auto scrollbar-themed">
      {/* Header */}
      <div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4 border-b border-border/60 pb-6 shrink-0">
        <div className="flex items-center gap-3 min-w-0">
          <Button
            type="button"
            variant="toolbar"
            tone="default"
            onClick={() => router.push("/users")}
            aria-label="Back to users"
          >
            <ArrowLeft size={18} />
          </Button>
          <div className="flex items-center gap-2 min-w-0">
            <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-accent/10 text-accent">
              <UserCog size={20} />
            </div>
            <div className="min-w-0">
              <h1 className="text-2xl sm:text-3xl font-extrabold text-[#101828] font-['Lexend'] tracking-tight">
                Edit User
              </h1>
              {user && (
                <p className="text-sm text-[#475467] font-normal truncate">
                  {user.name} · {user.email}
                </p>
              )}
            </div>
          </div>
        </div>
        {user && (
          <Button variant="outline" asChild>
            <Link href={`/users/${user.id}/permissions`}>
              <KeyRound size={16} /> Permissions
            </Link>
          </Button>
        )}
      </div>

      {userLoading && <Loading message="Loading user…" className="py-24" />}
      {isError && (
        <div className="rounded-2xl border border-destructive/20 bg-destructive/5 p-4 text-[13px] text-destructive">
          {error && typeof error === "object" && "data" in error
            ? String(
                (error as { data?: { message?: unknown } }).data?.message ??
                  "Failed to load user",
              )
            : "Failed to load user"}
        </div>
      )}

      {!userLoading && !isError && user && (
        <div className="space-y-10 pb-12">
          {/* KPI summary */}
          <div className="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-4 gap-6 shrink-0">
            <KPICard
              label="Role"
              value={getRoleName(user.role)}
              subtext="assigned role"
              icon={<KeyRound size={20} className="text-accent" />}
              className="bg-white/40 backdrop-blur-sm border-white/60 shadow-sm rounded-2xl"
            />
            <KPICard
              label="Leads"
              value={leads.length.toString()}
              subtext="owned or assigned"
              icon={<Target size={20} className="text-accent" />}
              className="bg-white/40 backdrop-blur-sm border-white/60 shadow-sm rounded-2xl"
            />
            <KPICard
              label="Deals"
              value={deals.length.toString()}
              subtext={`${formatCurrencyCompact(dealsValue)} pipeline`}
              icon={<Briefcase size={20} className="text-accent" />}
              className="bg-white/40 backdrop-blur-sm border-white/60 shadow-sm rounded-2xl"
            />
            <KPICard
              label="Customers"
              value={customers.length.toString()}
              subtext="owner or assigned AM"
              icon={<UsersIcon size={20} className="text-accent" />}
              className="bg-white/40 backdrop-blur-sm border-white/60 shadow-sm rounded-2xl"
            />
          </div>

          {/* Edit form */}
          <section>
            <div className="flex items-center gap-2 mb-4">
              <UserCog size={16} className="text-accent shrink-0" />
              <h2 className="font-['Lexend'] text-[15px] font-bold text-[#101828]">
                Account Details
              </h2>
            </div>
            <div className="rounded-[20px] border border-[#eaecf0] bg-white/70 backdrop-blur-md shadow-sm p-6">
              <div className="grid gap-6 md:grid-cols-[auto_1fr]">
                {/* Avatar */}
                <div className="flex flex-col items-center gap-3">
                  <div className="relative group">
                    <div className="relative size-24 rounded-full bg-accent/10 border-2 border-dashed border-accent/40 flex items-center justify-center overflow-hidden">
                      {filePreview ? (
                        <Image
                          src={filePreview}
                          alt="Preview"
                          fill
                          sizes="96px"
                          className="object-cover"
                          unoptimized={
                            filePreview.startsWith("blob:") ||
                            filePreview.startsWith("data:")
                          }
                        />
                      ) : user.avatar && getFullImageUrl(user.avatar) ? (
                        <Image
                          src={getFullImageUrl(user.avatar)!}
                          alt={user.name}
                          fill
                          sizes="96px"
                          className="object-cover"
                        />
                      ) : (
                        <Camera className="text-accent/40" size={32} />
                      )}
                    </div>
                    {canEdit && (
                      <Label
                        htmlFor="user-edit-image"
                        className="absolute inset-0 flex items-center justify-center bg-black/40 text-white rounded-full opacity-0 group-hover:opacity-100 cursor-pointer transition-opacity"
                      >
                        <Camera size={20} />
                      </Label>
                    )}
                    <input
                      id="user-edit-image"
                      type="file"
                      accept="image/*"
                      className="hidden"
                      disabled={!canEdit}
                      onChange={(e) => {
                        const file = e.target.files?.[0];
                        if (!file) return;
                        if (file.size > 600 * 1024) {
                          toast.error("Avatar image must be smaller than 600KB");
                          e.target.value = "";
                          return;
                        }
                        setValue("file", file);
                      }}
                    />
                  </div>
                  <p className="text-[11px] text-gray-500 font-medium text-center max-w-[120px]">
                    Click avatar to upload (optional)
                  </p>
                </div>

                {/* Fields */}
                <div className="grid gap-4 sm:grid-cols-2">
                  <div className="grid gap-2">
                    <Label htmlFor="user-edit-name">Name</Label>
                    <Controller
                      name="name"
                      control={control}
                      render={({ field }) => (
                        <Input
                          {...field}
                          id="user-edit-name"
                          placeholder="Full name"
                          disabled={!canEdit}
                        />
                      )}
                    />
                    {errors.name && (
                      <p className="text-[11px] text-destructive">
                        {errors.name.message}
                      </p>
                    )}
                  </div>

                  <div className="grid gap-2">
                    <Label htmlFor="user-edit-email">Email</Label>
                    <Controller
                      name="email"
                      control={control}
                      render={({ field }) => (
                        <Input
                          {...field}
                          id="user-edit-email"
                          type="email"
                          placeholder="user@example.com"
                          disabled={!canEdit}
                        />
                      )}
                    />
                    {errors.email && (
                      <p className="text-[11px] text-destructive">
                        {errors.email.message}
                      </p>
                    )}
                  </div>

                  <div className="grid gap-2">
                    <Label htmlFor="user-edit-password">
                      Password{" "}
                      <span className="text-[11px] text-muted-foreground">
                        (leave blank to keep current)
                      </span>
                    </Label>
                    <Controller
                      name="password"
                      control={control}
                      render={({ field }) => (
                        <div className="relative">
                          <Input
                            {...field}
                            id="user-edit-password"
                            type={showPassword ? "text" : "password"}
                            placeholder="Leave blank to keep"
                            className="pr-10"
                            disabled={!canEdit}
                          />
                          <Button
                            type="button"
                            variant="inputTrailingIcon"
                            onClick={() => setShowPassword((p) => !p)}
                            aria-label={
                              showPassword ? "Hide password" : "Show password"
                            }
                          >
                            {showPassword ? (
                              <EyeOff size={18} />
                            ) : (
                              <Eye size={18} />
                            )}
                          </Button>
                        </div>
                      )}
                    />
                    {errors.password && (
                      <p className="text-[11px] text-destructive">
                        {errors.password.message}
                      </p>
                    )}
                  </div>

                  <div className="grid gap-2">
                    <Label htmlFor="user-edit-role">Role</Label>
                    <Controller
                      name="role"
                      control={control}
                      render={({ field }) => (
                        <ReactSelect
                          id="user-edit-role"
                          value={field.value ? field.value : "none"}
                          onValueChange={(v) =>
                            field.onChange(v === "none" ? "" : v)
                          }
                          disabled={rolesLoading || !canEdit}
                          options={roleSelectOptions}
                          placeholder="Select role"
                          triggerClassName={cn(
                            usersRoleSelectTriggerClassName,
                            "w-full",
                          )}
                          contentClassName={usersRoleSelectContentClassName}
                        />
                      )}
                    />
                  </div>
                </div>
              </div>

              {canEdit && (
                <div className="flex justify-end gap-3 mt-6 pt-5 border-t border-border/60">
                  <Button variant="outline" onClick={() => router.push("/users")}>
                    Cancel
                  </Button>
                  <Button
                    onClick={onSubmit}
                    disabled={updating || bdrAeExportLoading}
                  >
                    {updating || bdrAeExportLoading ? "Saving..." : "Save changes"}
                  </Button>
                </div>
              )}
            </div>
          </section>

          {canViewPortfolio ? (
          <section>
            <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between mb-4">
              <div className="flex flex-col gap-1 min-w-0">
                <div className="flex items-center gap-2">
                  <Briefcase size={16} className="text-accent shrink-0" />
                  <h2 className="font-['Lexend'] text-[15px] font-bold text-[#101828]">
                    Portfolio
                  </h2>
                </div>
                <p className="text-[13px] text-[#475467] pl-6">{portfolioSummary}</p>
              </div>
              <Button
                type="button"
                variant="outline"
                size="sm"
                className="shrink-0"
                onClick={() => void handlePortfolioExport()}
                disabled={
                  exportingPortfolio ||
                  (portfolioTab === "leads"
                    ? leadsFetching && leads.length === 0
                    : portfolioTab === "deals"
                      ? dealsFetching && deals.length === 0
                      : customersFetching && customers.length === 0) ||
                  portfolioExportCount === 0
                }
              >
                <Download
                  size={14}
                  className={cn(exportingPortfolio && "animate-pulse")}
                />
                {exportingPortfolio ? "Exporting…" : "Export Excel"}
              </Button>
            </div>
            <Tabs
              value={portfolioTab}
              onValueChange={(value) =>
                setPortfolioTab(value as PortfolioExportTab)
              }
              className="w-full gap-4"
            >
              <TabsList className="h-auto min-h-10 w-full flex-wrap justify-start sm:w-fit">
                <TabsTrigger value="leads" className="gap-1.5 px-3">
                  <Target size={14} />
                  Leads
                  <span className="text-[11px] font-semibold text-[#667085]">
                    ({leads.length})
                  </span>
                </TabsTrigger>
                <TabsTrigger value="deals" className="gap-1.5 px-3">
                  <Briefcase size={14} />
                  Deals
                  <span className="text-[11px] font-semibold text-[#667085]">
                    ({deals.length})
                  </span>
                </TabsTrigger>
                <TabsTrigger value="customers" className="gap-1.5 px-3">
                  <UsersIcon size={14} />
                  Customers
                  <span className="text-[11px] font-semibold text-[#667085]">
                    ({customers.length})
                  </span>
                </TabsTrigger>
              </TabsList>

              <TabsContent value="leads" className="mt-0 outline-none">
                <div className={tabPanelCardClassName}>
                  {leadsFetching && leads.length === 0 ? (
                    <Loading message="Loading leads…" className="py-12" />
                  ) : leads.length === 0 ? (
                    <NoDataFound
                      message="No leads"
                      description="This user does not own or appear on any leads as AE, BDR, or contributor."
                    />
                  ) : (
                    <UserPortfolioDealsTable
                      rows={leads}
                      userId={id}
                      pipelineStages={pipelineStages}
                      highlightAe={viewedUserIsBdr}
                      highlightBdr={viewedUserIsAe}
                      nameColumnLabel="Lead"
                    />
                  )}
                </div>
              </TabsContent>

              <TabsContent value="deals" className="mt-0 outline-none">
                <div className={tabPanelCardClassName}>
                  {dealsFetching && deals.length === 0 ? (
                    <Loading message="Loading deals…" className="py-12" />
                  ) : deals.length === 0 ? (
                    <NoDataFound
                      message="No deals"
                      description="This user does not own or appear on any deals as AE, BDR, or contributor."
                    />
                  ) : (
                    <UserPortfolioDealsTable
                      rows={deals}
                      userId={id}
                      pipelineStages={pipelineStages}
                      highlightAe={viewedUserIsBdr}
                      highlightBdr={viewedUserIsAe}
                      nameColumnLabel="Deal"
                    />
                  )}
                </div>
              </TabsContent>

              <TabsContent value="customers" className="mt-0 outline-none">
                <div className={tabPanelCardClassName}>
                  {customersFetching && customers.length === 0 ? (
                    <Loading message="Loading customers…" className="py-12" />
                  ) : customers.length === 0 ? (
                    <NoDataFound
                      message="No customers"
                      description="This user is not the owner or assigned account manager on any customers."
                    />
                  ) : (
                    <div className="overflow-x-auto scrollbar-themed">
                      <Table variant="transparent">
                        <TableHeader>
                          <TableRow className="hover:bg-transparent border-b border-[#eaecf0] bg-[#f9fafb]/80">
                            <TableHead className="font-bold text-[#475467] text-[11px] uppercase tracking-wider py-3.5">
                              Customer
                            </TableHead>
                            <TableHead className="font-bold text-[#475467] text-[11px] uppercase tracking-wider py-3.5">
                              Your role
                            </TableHead>
                            <TableHead className="font-bold text-[#475467] text-[11px] uppercase tracking-wider py-3.5">
                              Owner
                            </TableHead>
                            <TableHead
                              className={cn(
                                "font-bold text-[#475467] text-[11px] uppercase tracking-wider py-3.5",
                                viewedUserIsAe && "text-accent",
                              )}
                            >
                              Assigned AM{viewedUserIsAe ? " (you)" : ""}
                            </TableHead>
                            <TableHead className="font-bold text-[#475467] text-[11px] uppercase tracking-wider py-3.5">
                              Email
                            </TableHead>
                            <TableHead className="font-bold text-[#475467] text-[11px] uppercase tracking-wider py-3.5">
                              Status
                            </TableHead>
                            <TableHead className="font-bold text-[#475467] text-[11px] uppercase tracking-wider py-3.5">
                              Lifetime Value
                            </TableHead>
                          </TableRow>
                        </TableHeader>
                        <TableBody>
                          {customers.map((customer) => (
                            <TableRow
                              key={customer.id}
                              className="border-b border-[#eaecf0] hover:bg-[#f9fafb] transition-colors"
                            >
                              <TableCell className="py-3 font-semibold text-[13px]">
                                <Link
                                  href={`/customers/${customer.id}`}
                                  className="text-[#101828] hover:text-accent hover:underline"
                                >
                                  {customer.fullName?.trim() ||
                                    customer.companyName?.trim() ||
                                    customer.customerName?.trim() ||
                                    "Unnamed"}
                                </Link>
                              </TableCell>
                              <TableCell className="py-3 text-[13px] text-[#475467]">
                                {resolveCustomerAssignmentRole(customer, id)}
                              </TableCell>
                              <TableCell className="py-3 text-[13px] text-[#475467]">
                                {customer.owner?.name?.trim() || "—"}
                              </TableCell>
                              <TableCell
                                className={cn(
                                  "py-3 text-[13px]",
                                  viewedUserIsAe && customer.assignedAmId === id
                                    ? "font-medium text-[#101828]"
                                    : "text-[#475467]",
                                )}
                              >
                                {customer.assignedAm?.name?.trim() || "—"}
                              </TableCell>
                              <TableCell className="py-3 text-[13px] text-[#475467]">
                                {customer.email || "—"}
                              </TableCell>
                              <TableCell className="py-3">
                                <span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-[11px] font-semibold bg-[#f2f4f7] text-[#344054] border border-[#d0d5dd]">
                                  {customer.customerStatus || "—"}
                                </span>
                              </TableCell>
                              <TableCell className="py-3 text-[13px] text-[#475467]">
                                {formatCurrencyCompact(
                                  toNumber(customer.totalLifetimeValue),
                                )}
                              </TableCell>
                            </TableRow>
                          ))}
                        </TableBody>
                      </Table>
                    </div>
                  )}
                </div>
              </TabsContent>
            </Tabs>
          </section>
          ) : null}
        </div>
      )}

    </div>
  );
}
