"use client";

import * as React from "react";
import Link from "next/link";
import { useSession } from "next-auth/react";
import { toast } from "sonner";
import {
  ArrowLeft,
  Link2,
  Loader2,
  Search,
  Unlink,
} from "lucide-react";
import { useAuthToken } from "@/hooks/use-auth-token";
import { useGetProfileQuery } from "@/api/rtk/auth-api";
import { hasPermission } from "@/lib/permissions";
import { NoDataFound } from "@/components/ui/no-data-found";
import { Loading } from "@/components/ui/loading";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { ReactSelect } from "@/components/ui/react-select";
import { Can } from "@/components/providers/ability-provider";
import {
  useClearAeBdrPairMutation,
  useGetAeBdrPairsQuery,
  useGetAllUsersQuery,
  useGetTeamsQuery,
  useUpsertAeBdrPairMutation,
  type AeBdrPairKind,
  type AeBdrPairListItem,
  type AeBdrPairedUser,
} from "@/api/rtk/teams-api";
import { useGetDivisionsQuery } from "@/api/rtk/divisions-api";
import { formatTeamLabelForUi } from "@/lib/deal-display";
import { cn } from "@/lib/utils";

function isBdrRoleName(name?: string | null): boolean {
  const r = typeof name === "string" ? name.trim().toLowerCase() : "";
  return (
    r === "bdr" ||
    r === "business development representative" ||
    r === "business development rep"
  );
}

function pairSaveKey(aeUserId: string, pairKind: AeBdrPairKind) {
  return `${aeUserId}:${pairKind}`;
}

function BdrTagCell({
  label,
  paired,
  canEdit,
  bdrOptions,
  cellStateKey,
  savingKey,
  clearingKey,
  onSave,
  onClear,
}: {
  label: string;
  paired: AeBdrPairedUser | null;
  canEdit: boolean;
  bdrOptions: Array<{ value: string; label: string }>;
  cellStateKey: string;
  savingKey: string | null;
  clearingKey: string | null;
  onSave: (bdrUserId: string) => void;
  onClear: () => void;
}) {
  const isSaving = savingKey === cellStateKey;
  const isClearing = clearingKey === cellStateKey;

  if (!canEdit) {
    return (
      <div className="min-w-[180px]">
        <p className="mb-1 text-[10px] font-black uppercase tracking-[0.08em] text-gray-400 font-['Lexend_Deca']">
          {label}
        </p>
        <span className="text-[13px] text-gray-700">{paired?.name ?? "—"}</span>
      </div>
    );
  }

  return (
    <div className="min-w-[180px]">
      <p className="mb-1 text-[10px] font-black uppercase tracking-[0.08em] text-gray-400 font-['Lexend_Deca']">
        {label}
      </p>
      <ReactSelect
        options={bdrOptions}
        value={paired?.userId ?? ""}
        onChange={(next) => {
          const id = typeof next === "string" ? next : "";
          if (id) onSave(id);
        }}
        placeholder={`Select ${label} BDR…`}
        isDisabled={isSaving || isClearing}
        isClearable={false}
      />
      {paired && (
        <Can action="update" subject="team">
          <Button
            variant="ghost"
            size="sm"
            className="mt-1 h-7 gap-1 px-1 text-[11px] text-gray-500"
            disabled={isSaving || isClearing}
            onClick={onClear}
          >
            {isClearing ? (
              <Loader2 size={12} className="animate-spin" />
            ) : (
              <Unlink size={12} />
            )}
            Clear
          </Button>
        </Can>
      )}
      {isSaving && (
        <span className="mt-1 flex items-center gap-1 text-[11px] text-gray-500">
          <Loader2 size={12} className="animate-spin" /> Saving…
        </span>
      )}
    </div>
  );
}

export default function AeBdrPairsPage() {
  const { token } = useAuthToken();
  const { data: session } = useSession();
  const { data: profile } = useGetProfileQuery(undefined, { skip: !token });
  const permissionSource =
    (session as { backendUser?: unknown } | null)?.backendUser ?? profile ?? null;

  const canReadTeam = hasPermission(permissionSource, ["READ", "VIEW"], "TEAM");
  const canUpdateTeam = hasPermission(permissionSource, "UPDATE", "TEAM");

  const [searchInput, setSearchInput] = React.useState("");
  const [search, setSearch] = React.useState("");
  const [divisionId, setDivisionId] = React.useState<string | null>(null);
  const [teamId, setTeamId] = React.useState<string | null>(null);
  const [savingKey, setSavingKey] = React.useState<string | null>(null);
  const [clearingKey, setClearingKey] = React.useState<string | null>(null);

  React.useEffect(() => {
    const timer = setTimeout(() => setSearch(searchInput.trim()), 300);
    return () => clearTimeout(timer);
  }, [searchInput]);

  const { data: divisions = [] } = useGetDivisionsQuery(undefined, {
    skip: !token || !canReadTeam,
  });
  const { data: teams = [] } = useGetTeamsQuery(undefined, {
    skip: !token || !canReadTeam,
  });
  const { data: allUsers = [] } = useGetAllUsersQuery(undefined, {
    skip: !token || !canReadTeam,
  });

  const {
    data: pairs = [],
    isLoading,
    isFetching,
  } = useGetAeBdrPairsQuery(
    {
      search: search || undefined,
      divisionId: divisionId ?? undefined,
      teamId: teamId ?? undefined,
    },
    { skip: !token || !canReadTeam },
  );

  const [upsertPair] = useUpsertAeBdrPairMutation();
  const [clearPair] = useClearAeBdrPairMutation();

  const bdrOptions = React.useMemo(
    () =>
      allUsers
        .filter((u) => isBdrRoleName(u.role?.name))
        .map((u) => ({ value: u.id, label: u.name })),
    [allUsers],
  );

  const divisionOptions = React.useMemo(
    () => divisions.map((d) => ({ value: d.id, label: d.name })),
    [divisions],
  );

  const teamOptions = React.useMemo(
    () =>
      teams
        .filter((t) => !divisionId || t.divisionId === divisionId)
        .map((t) => ({
          value: t.id,
          label: formatTeamLabelForUi(t.name),
        })),
    [teams, divisionId],
  );

  const pairedCount = pairs.filter(
    (p) => p.frontBdr || p.supportBdr,
  ).length;

  const handleSave = async (
    aeUserId: string,
    pairKind: AeBdrPairKind,
    bdrUserId: string,
    label: string,
  ) => {
    setSavingKey(pairSaveKey(aeUserId, pairKind));
    try {
      await upsertPair({ aeUserId, bdrUserId, pairKind }).unwrap();
      toast.success(`${label} BDR pairing saved`);
    } catch (error: unknown) {
      const err = error as { data?: { message?: string } };
      toast.error(err?.data?.message ?? "Failed to save pairing");
    } finally {
      setSavingKey(null);
    }
  };

  const handleClear = async (
    aeUserId: string,
    pairKind: AeBdrPairKind,
    label: string,
  ) => {
    const key = pairSaveKey(aeUserId, pairKind);
    setClearingKey(key);
    try {
      await clearPair({ aeUserId, pairKind }).unwrap();
      toast.success(`${label} BDR pairing cleared`);
    } catch (error: unknown) {
      const err = error as { data?: { message?: string } };
      toast.error(err?.data?.message ?? "Failed to clear pairing");
    } finally {
      setClearingKey(null);
    }
  };

  const renderBdrCell = (
    row: AeBdrPairListItem,
    pairKind: AeBdrPairKind,
    label: string,
    paired: AeBdrPairedUser | null,
  ) => (
    <BdrTagCell
      label={label}
      paired={paired}
      canEdit={canUpdateTeam}
      bdrOptions={bdrOptions}
      cellStateKey={pairSaveKey(row.aeUserId, pairKind)}
      savingKey={savingKey}
      clearingKey={clearingKey}
      onSave={(bdrUserId) => handleSave(row.aeUserId, pairKind, bdrUserId, label)}
      onClear={() => handleClear(row.aeUserId, pairKind, label)}
    />
  );

  if (!canReadTeam) {
    return (
      <div className="flex h-full items-center justify-center p-4">
        <NoDataFound
          message="Teams access required"
          description="You need READ permission on TEAM to view AE–BDR pairings."
        />
      </div>
    );
  }

  return (
    <div className="flex h-full flex-col gap-4.5 overflow-y-auto p-1 sm:p-2 md:p-4 animate-in fade-in duration-500 scrollbar-themed">
      <div className="flex flex-col gap-4 rounded-2xl border border-white/40 bg-white/50 p-4 shadow-[0px_2px_20px_0px_rgba(0,0,0,0.06)] backdrop-blur-[15px] dark:bg-white/10 md:flex-row md:items-center md:justify-between md:p-5">
        <div className="flex items-start gap-3">
          <Link
            href="/teams"
            className="mt-1 flex h-9 w-9 shrink-0 items-center justify-center rounded-xl border border-white/40 bg-white/60 text-gray-600 transition-colors hover:bg-white/80"
            title="Back to Teams"
          >
            <ArrowLeft size={16} />
          </Link>
          <div className="flex flex-col shrink-0">
            <p className="text-[11px] font-bold uppercase tracking-wider text-gray-400 font-['Lexend_Deca']">
              Teams / AE–BDR Pairs
            </p>
            <h1 className="text-[25px] font-extrabold leading-none tracking-tight text-text font-['Lexend']">
              AE–BDR Pairs
            </h1>
            <p className="mt-2 text-[12px] uppercase tracking-wider text-gray-500 font-['Lexend_Deca']">
              <span className="font-bold text-text/80">{pairs.length} AEs</span>
              <span className="mx-1 opacity-50">·</span>
              <span className="font-bold text-accent/90">{pairedCount} with pairings</span>
            </p>
          </div>
        </div>

        <div className="flex w-full flex-col gap-2 sm:flex-row sm:flex-wrap md:w-auto md:justify-end">
          <div className="relative min-w-[150px] flex-1 sm:max-w-[200px]">
            <Search
              size={14}
              className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"
            />
            <Input
              type="search"
              placeholder="Search AE…"
              className="h-10 w-full rounded-xl border border-white/60 bg-white/60 pl-9 pr-3 text-[13px] shadow-[0px_2px_15px_0px_rgba(0,0,0,0.06)] backdrop-blur-[15px] font-['Lexend_Deca'] dark:bg-white/10"
              value={searchInput}
              onChange={(e) => setSearchInput(e.target.value)}
            />
          </div>
          <div className="min-w-[160px] flex-1 sm:max-w-[180px]">
            <ReactSelect
              options={divisionOptions}
              value={divisionId ?? ""}
              onChange={(v) => {
                setDivisionId(v || null);
                setTeamId(null);
              }}
              placeholder="All divisions"
              isClearable
            />
          </div>
          <div className="min-w-[160px] flex-1 sm:max-w-[180px]">
            <ReactSelect
              options={teamOptions}
              value={teamId ?? ""}
              onChange={(v) => setTeamId(v || null)}
              placeholder="All teams"
              isClearable
            />
          </div>
        </div>
      </div>

      <div className="rounded-2xl border border-white/40 bg-white/50 shadow-[0px_2px_20px_0px_rgba(0,0,0,0.06)] backdrop-blur-[15px] dark:bg-white/10">
        {isLoading ? (
          <div className="flex min-h-[240px] items-center justify-center p-8">
            <Loading />
          </div>
        ) : pairs.length === 0 ? (
          <div className="p-8">
            <NoDataFound
              message="No account executives found"
              description="Try adjusting filters or ensure AEs are assigned to teams."
            />
          </div>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full min-w-[900px] border-collapse">
              <thead>
                <tr className="border-b border-gray-100/80 text-left">
                  {[
                    "Account Executive",
                    "Teams",
                    "Division",
                    "Front BDR",
                    "Support BDR",
                  ].map((col) => (
                    <th
                      key={col}
                      className="px-4 py-3 text-[10px] font-black uppercase tracking-[0.09em] text-gray-400 font-['Lexend_Deca']"
                    >
                      {col}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {pairs.map((row) => (
                  <tr
                    key={row.aeUserId}
                    className={cn(
                      "border-b border-gray-50 transition-colors hover:bg-white/40",
                      isFetching && "opacity-80",
                    )}
                  >
                    <td className="px-4 py-3">
                      <div className="flex items-center gap-3">
                        <div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-[#6C63FF] to-[#8B83FF] text-[11px] font-black text-white">
                          {row.aeName.slice(0, 2).toUpperCase()}
                        </div>
                        <div className="min-w-0">
                          <p className="truncate text-[13px] font-semibold text-gray-900">
                            {row.aeName}
                          </p>
                          <p className="truncate text-[11px] text-gray-500">{row.aeEmail}</p>
                        </div>
                      </div>
                    </td>
                    <td className="px-4 py-3">
                      <div className="flex flex-wrap gap-1">
                        {row.teams.length === 0 ? (
                          <span className="text-[12px] text-gray-400">—</span>
                        ) : (
                          row.teams.map((t) => (
                            <span
                              key={t.id}
                              className="inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-bold text-gray-700"
                              style={{ backgroundColor: `${t.color}22` }}
                            >
                              <span
                                className="h-2 w-2 rounded-full"
                                style={{ backgroundColor: t.color }}
                              />
                              {formatTeamLabelForUi(t.name)}
                            </span>
                          ))
                        )}
                      </div>
                    </td>
                    <td className="px-4 py-3">
                      <span className="text-[13px] text-gray-700">
                        {row.divisionNames.length
                          ? row.divisionNames.join(", ")
                          : "—"}
                      </span>
                    </td>
                    <td className="px-4 py-3">
                      {renderBdrCell(row, "FRONT", "Front", row.frontBdr)}
                    </td>
                    <td className="px-4 py-3">
                      {renderBdrCell(row, "SUPPORT", "BDR", row.supportBdr)}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>

      <p className="flex items-center gap-2 px-1 text-[11px] text-gray-500 font-['Lexend_Deca']">
        <Link2 size={12} />
        Assign Front and Support BDRs separately — pairings are reference only and do not auto-assign on leads.
      </p>
    </div>
  );
}
