"use client";

import * as React from "react";
import type {
  MarketingAeAssociateBreakdown,
  MarketingAeMetrics,
  MarketingAnalyticsResponse,
  MarketingBdrAssociateBreakdown,
  MarketingBdrMetrics,
  MarketingTeamBreakdown,
} from "@/api/rtk/marketing-api";
import { TeamSelect } from "@/components/shared/team-select";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
import { cn } from "@/lib/utils";
import { sumAllocatedAeSpending } from "@/features/marketing/utils/marketing-drill-helpers";
import {
  formatMarketingCount,
  formatMarketingCurrency,
  formatMarketingPercent,
  formatMarketingRatio,
} from "./marketing-kpi-card";

// ─── View model ───────────────────────────────────────────────────────────────

type AeOverallView = MarketingAeMetrics & { byChannel: MarketingAeMetrics[] };

type TeamViewModel = {
  teamId: string;
  teamName: string;
  aeAssociates: MarketingAeAssociateBreakdown[];
  aeOverall: AeOverallView;
  bdrAssociates: MarketingBdrAssociateBreakdown[];
  bdrOverall: MarketingBdrMetrics;
};

function aggregateAeChannels(
  associates: MarketingAeAssociateBreakdown[],
): MarketingAeMetrics[] {
  const map = new Map<
    string,
    { spending: number; leads: number; accounts: number; frontRevenue: number }
  >();

  for (const associate of associates) {
    for (const row of associate.channels) {
      const prev = map.get(row.channel) ?? {
        spending: 0,
        leads: 0,
        accounts: 0,
        frontRevenue: 0,
      };
      prev.spending += row.spending;
      prev.leads += row.leads;
      prev.accounts += row.accounts;
      prev.frontRevenue += row.frontRevenue;
      map.set(row.channel, prev);
    }
  }

  return [...map.entries()]
    .sort(([a], [b]) => a.localeCompare(b))
    .map(([channel, raw]) => {
      const cpl = raw.leads > 0 ? raw.spending / raw.leads : null;
      const averageAccountValue =
        raw.accounts > 0 ? raw.frontRevenue / raw.accounts : null;
      const conversionRatioPct =
        raw.leads > 0 ? (raw.accounts / raw.leads) * 100 : null;
      const roiPct =
        raw.spending > 0 ? (raw.frontRevenue / raw.spending) * 100 : null;
      const cpa = raw.accounts > 0 ? raw.spending / raw.accounts : null;

      return {
        channel,
        spending: raw.spending,
        leads: raw.leads,
        cpl,
        accounts: raw.accounts,
        frontRevenue: raw.frontRevenue,
        averageAccountValue,
        conversionRatioPct,
        cpa,
        frontRevenueMinusMarketing: raw.frontRevenue - raw.spending,
        roiPct,
      };
    });
}

function withAllocatedOverallSpending(
  overall: MarketingAeMetrics,
  allocatedSpending: number,
): MarketingAeMetrics {
  const { leads, accounts, frontRevenue } = overall;
  const cpl = leads > 0 ? allocatedSpending / leads : null;
  const cpa = accounts > 0 ? allocatedSpending / accounts : null;
  const frontRevenueMinusMarketing = frontRevenue - allocatedSpending;
  const roiPct =
    allocatedSpending > 0 ? (frontRevenue / allocatedSpending) * 100 : null;

  return {
    ...overall,
    spending: allocatedSpending,
    cpl,
    cpa,
    frontRevenueMinusMarketing,
    roiPct,
  };
}

function mapTeamBreakdown(team: MarketingTeamBreakdown): TeamViewModel {
  const allocatedSpending = sumAllocatedAeSpending([team]);

  return {
    teamId: team.teamId,
    teamName: team.teamName,
    aeAssociates: team.ae.associates,
    aeOverall: {
      ...withAllocatedOverallSpending(team.ae.overall, allocatedSpending),
      byChannel: aggregateAeChannels(team.ae.associates),
    },
    bdrAssociates: team.bdr.associates,
    bdrOverall: team.bdr.overall,
  };
}

function emptyAeMetrics(channel = "Overall"): MarketingAeMetrics {
  return {
    channel,
    spending: 0,
    leads: 0,
    cpl: null,
    accounts: 0,
    frontRevenue: 0,
    averageAccountValue: null,
    conversionRatioPct: null,
    cpa: null,
    frontRevenueMinusMarketing: 0,
    roiPct: null,
  };
}

function emptyBdrMetrics(channel = "Overall"): MarketingBdrMetrics {
  return {
    channel,
    leads: 0,
    contactedLeads: 0,
    followUpScheduled: 0,
    closedLost: 0,
    discoveryMeetingBooked: 0,
    connectivityPct: null,
    discoveryMeetingBookedPct: null,
    closedLostPct: null,
  };
}

function buildFallbackTeamFromAnalytics(
  data?: MarketingAnalyticsResponse,
): TeamViewModel {
  const overall: MarketingAeMetrics = data
    ? withAllocatedOverallSpending(
        {
          channel: "Overall",
          spending: data.spending,
          leads: data.leads,
          cpl: data.cpl,
          accounts: data.accounts,
          frontRevenue: data.frontRevenue,
          averageAccountValue: data.averageAccountValue,
          conversionRatioPct: data.conversionRatioPct,
          cpa: data.cpa,
          frontRevenueMinusMarketing: data.frontRevenueMinusMarketing,
          roiPct: data.roiPct,
        },
        data.spending,
      )
    : emptyAeMetrics();

  return {
    teamId: "all",
    teamName: "All Teams",
    aeAssociates: [],
    aeOverall: { ...overall, byChannel: [] },
    bdrAssociates: [],
    bdrOverall: emptyBdrMetrics(),
  };
}

// ─── Table chrome ─────────────────────────────────────────────────────────────

const thClass =
  "px-3 py-3 text-left text-[10px] font-bold uppercase tracking-wider text-gray-500 whitespace-nowrap border-b border-gray-200/80 bg-gray-50/95 backdrop-blur-sm";
const thRightClass = cn(thClass, "text-right");
const tdBase = "px-3 py-2.5 text-xs text-gray-700 whitespace-nowrap tabular-nums";
const tdRight = cn(tdBase, "text-right");
const associateClass =
  "px-3 py-2.5 text-xs font-semibold text-[#1d1d39] align-top bg-violet-50/40 border-r border-gray-100 max-w-[148px]";
const channelClass = "px-3 py-2.5 text-xs font-medium text-gray-600";
const bodyRowClass =
  "border-b border-gray-100/80 transition-colors hover:bg-gray-50/60";
const totalRowClass = "bg-slate-100/90 font-semibold text-slate-800";
const overallRowClass =
  "bg-[#6C63FF]/[0.07] font-bold text-[#1d1d39] border-t-2 border-[#6C63FF]/15";

const AE_HEADERS = [
  { label: "MKTG Channel", align: "left" as const },
  { label: "Spending", align: "right" as const },
  { label: "Leads", align: "right" as const },
  { label: "CPL", align: "right" as const },
  { label: "Customers", align: "right" as const },
  { label: "Front Revenue", align: "right" as const },
  { label: "Avg Customer Value", align: "right" as const },
  { label: "Conversion %", align: "right" as const },
  { label: "CPA", align: "right" as const },
  { label: "F Rev − MKTG", align: "right" as const },
  { label: "ROI %", align: "right" as const },
];

const BDR_HEADERS = [
  { label: "MKTG Channel", align: "left" as const },
  { label: "Leads", align: "right" as const },
  { label: "Contacted", align: "right" as const },
  { label: "Follow-up", align: "right" as const },
  { label: "Closed Lost", align: "right" as const },
  { label: "Discovery Mtg", align: "right" as const },
  { label: "Connectivity %", align: "right" as const },
  { label: "Discovery %", align: "right" as const },
  { label: "Closed Lost %", align: "right" as const },
];

// ─── Metric cells ─────────────────────────────────────────────────────────────

function AeMetricCells({
  row,
  variant = "body",
}: {
  row: MarketingAeMetrics;
  variant?: "body" | "total" | "overall";
}) {
  const cell =
    variant === "body"
      ? tdRight
      : variant === "total"
        ? cn(tdRight, totalRowClass)
        : cn(tdRight, overallRowClass);

  const negClass =
    row.frontRevenueMinusMarketing < 0 ? "text-rose-600" : undefined;

  return (
    <>
      <td className={cell}>{formatMarketingCurrency(row.spending)}</td>
      <td className={cell}>{formatMarketingCount(row.leads)}</td>
      <td className={cell}>{formatMarketingRatio(row.cpl)}</td>
      <td className={cell}>{formatMarketingCount(row.accounts)}</td>
      <td className={cell}>{formatMarketingCurrency(row.frontRevenue)}</td>
      <td className={cell}>{formatMarketingRatio(row.averageAccountValue)}</td>
      <td className={cell}>{formatMarketingPercent(row.conversionRatioPct)}</td>
      <td className={cell}>{formatMarketingRatio(row.cpa)}</td>
      <td className={cn(cell, negClass)}>
        {formatMarketingCurrency(row.frontRevenueMinusMarketing)}
      </td>
      <td className={cell}>{formatMarketingPercent(row.roiPct)}</td>
    </>
  );
}

function BdrMetricCells({
  row,
  variant = "body",
}: {
  row: MarketingBdrMetrics;
  variant?: "body" | "total" | "overall";
}) {
  const cell =
    variant === "body"
      ? tdRight
      : variant === "total"
        ? cn(tdRight, totalRowClass)
        : cn(tdRight, overallRowClass);

  return (
    <>
      <td className={cell}>{formatMarketingCount(row.leads)}</td>
      <td className={cell}>{formatMarketingCount(row.contactedLeads)}</td>
      <td className={cell}>{formatMarketingCount(row.followUpScheduled)}</td>
      <td className={cell}>{formatMarketingCount(row.closedLost)}</td>
      <td className={cell}>
        {formatMarketingCount(row.discoveryMeetingBooked)}
      </td>
      <td className={cell}>{formatMarketingPercent(row.connectivityPct)}</td>
      <td className={cell}>
        {formatMarketingPercent(row.discoveryMeetingBookedPct)}
      </td>
      <td className={cell}>{formatMarketingPercent(row.closedLostPct)}</td>
    </>
  );
}

// ─── Shell & head ─────────────────────────────────────────────────────────────

function AnalyticsTableSection({
  title,
  subtitle,
  children,
  className,
}: {
  title: string;
  subtitle: string;
  children: React.ReactNode;
  className?: string;
}) {
  return (
    <section className={cn("min-w-0", className)}>
      <header className="border-b border-gray-100/80 bg-white/30 px-5 py-3.5">
        <h3 className="font-['Lexend'] text-sm font-extrabold tracking-tight text-text">
          {title}
        </h3>
        <p className="mt-0.5 text-xs font-semibold uppercase tracking-wide text-gray-500">
          {subtitle}
        </p>
      </header>
      <div className="overflow-x-auto scrollbar-themed">{children}</div>
    </section>
  );
}

function TeamAnalyticsGroupCard({
  teamName,
  showTeamName,
  children,
}: {
  teamName: string;
  showTeamName: boolean;
  children: React.ReactNode;
}) {
  return (
    <Card className="gap-0 overflow-hidden py-0">
      {showTeamName ? (
        <CardHeader className="border-b border-gray-100/80 bg-white/30 px-5 py-4">
          <CardTitle className="font-['Lexend'] text-base font-extrabold tracking-tight text-text">
            {teamName}
          </CardTitle>
          <CardDescription className="text-xs font-semibold uppercase tracking-wide text-gray-500">
            AE &amp; BDR performance breakdown
          </CardDescription>
        </CardHeader>
      ) : null}
      <CardContent className="flex flex-col gap-0 p-0">{children}</CardContent>
    </Card>
  );
}

function TableHead({
  associateLabel,
  headers,
}: {
  associateLabel: string;
  headers: { label: string; align: "left" | "right" }[];
}) {
  return (
    <thead className="sticky top-0 z-10">
      <tr>
        <th className={cn(thClass, "min-w-[132px]")}>{associateLabel}</th>
        {headers.map((h) => (
          <th
            key={h.label}
            className={h.align === "right" ? thRightClass : thClass}
          >
            {h.label}
          </th>
        ))}
      </tr>
    </thead>
  );
}

function EmptyTableRow({
  colSpan,
  message,
}: {
  colSpan: number;
  message: string;
}) {
  return (
    <tr>
      <td
        colSpan={colSpan}
        className="px-5 py-10 text-center text-sm text-gray-500 font-['Lexend_Deca']"
      >
        {message}
      </td>
    </tr>
  );
}

// ─── Row groups ───────────────────────────────────────────────────────────────

function AeAssociateRows({
  associate,
}: {
  associate: MarketingAeAssociateBreakdown;
}) {
  const { name, channels, total } = associate;

  if (channels.length === 0) {
    return (
      <tr className={bodyRowClass}>
        <td className={associateClass}>{name}</td>
        <td className={channelClass} colSpan={AE_HEADERS.length}>
          No channel data
        </td>
      </tr>
    );
  }

  return (
    <>
      {channels.map((row, i) => (
        <tr key={row.channel} className={bodyRowClass}>
          {i === 0 ? (
            <td rowSpan={channels.length + 1} className={associateClass}>
              {name}
            </td>
          ) : null}
          <td className={channelClass}>{row.channel}</td>
          <AeMetricCells row={row} />
        </tr>
      ))}
      <tr className={totalRowClass}>
        <td className={cn(channelClass, totalRowClass, "font-semibold")}>
          Total
        </td>
        <AeMetricCells row={total} variant="total" />
      </tr>
    </>
  );
}

function AeOverallRows({ overall }: { overall: AeOverallView }) {
  const channelRows = overall.byChannel;

  if (channelRows.length === 0) {
    return (
      <tr className={overallRowClass}>
        <td className={cn(associateClass, overallRowClass)}>Overall</td>
        <td className={cn(channelClass, overallRowClass)}>—</td>
        <AeMetricCells row={overall} variant="overall" />
      </tr>
    );
  }

  return (
    <>
      {channelRows.map((row, i) => (
        <tr key={row.channel} className={bodyRowClass}>
          {i === 0 ? (
            <td
              rowSpan={channelRows.length + 1}
              className={cn(associateClass, "bg-[#6C63FF]/[0.06] font-bold")}
            >
              Overall
            </td>
          ) : null}
          <td className={channelClass}>{row.channel}</td>
          <AeMetricCells row={row} />
        </tr>
      ))}
      <tr className={overallRowClass}>
        <td className={cn(channelClass, overallRowClass, "font-bold")}>
          Total
        </td>
        <AeMetricCells row={overall} variant="overall" />
      </tr>
    </>
  );
}

function BdrAssociateRows({
  associate,
}: {
  associate: MarketingBdrAssociateBreakdown;
}) {
  const { name, channels, total } = associate;

  if (channels.length === 0) {
    return (
      <tr className={bodyRowClass}>
        <td className={associateClass}>{name}</td>
        <td className={channelClass}>—</td>
        <BdrMetricCells row={total} />
      </tr>
    );
  }

  return (
    <>
      {channels.map((row, i) => (
        <tr key={row.channel} className={bodyRowClass}>
          {i === 0 ? (
            <td rowSpan={channels.length + 1} className={associateClass}>
              {name}
            </td>
          ) : null}
          <td className={channelClass}>{row.channel}</td>
          <BdrMetricCells row={row} />
        </tr>
      ))}
      <tr className={totalRowClass}>
        <td className={cn(channelClass, totalRowClass, "font-semibold")}>
          Total
        </td>
        <BdrMetricCells row={total} variant="total" />
      </tr>
    </>
  );
}

function BdrOverallRow({ overall }: { overall: MarketingBdrMetrics }) {
  return (
    <tr className={overallRowClass}>
      <td className={cn(associateClass, overallRowClass, "font-bold")}>
        Overall
      </td>
      <td className={cn(channelClass, overallRowClass)}>—</td>
      <BdrMetricCells row={overall} variant="overall" />
    </tr>
  );
}

function LoadingTableSection({
  titleWidth,
  colCount,
}: {
  titleWidth: string;
  colCount: number;
}) {
  return (
    <section className="border-t border-gray-100/80 first:border-t-0">
      <div className="border-b border-gray-100/80 bg-white/30 px-5 py-3.5">
        <Skeleton className={cn("h-4 rounded-lg", titleWidth)} />
        <Skeleton className="mt-2 h-3 w-56 rounded-md" />
      </div>
      <div className="space-y-2 p-5">
        {Array.from({ length: 4 }).map((_, i) => (
          <Skeleton key={i} className="h-9 w-full rounded-lg bg-gray-200/70" />
        ))}
      </div>
      <span className="sr-only">Loading table with {colCount} columns</span>
    </section>
  );
}

function LoadingTeamGroupCard() {
  return (
    <Card className="gap-0 overflow-hidden py-0">
      <CardHeader className="border-b border-gray-100/80 bg-white/30 px-5 py-4">
        <Skeleton className="h-5 w-40 rounded-lg" />
        <Skeleton className="mt-2 h-3 w-52 rounded-md" />
      </CardHeader>
      <CardContent className="flex flex-col gap-0 p-0">
        <LoadingTableSection titleWidth="w-44" colCount={AE_HEADERS.length + 1} />
        <LoadingTableSection titleWidth="w-52" colCount={BDR_HEADERS.length + 1} />
      </CardContent>
    </Card>
  );
}

// ─── Export ───────────────────────────────────────────────────────────────────

export type MarketingTeamAnalyticsTablesProps = {
  teams: MarketingTeamBreakdown[];
  analytics?: MarketingAnalyticsResponse;
  isLoading?: boolean;
  teamId?: string;
  onTeamIdChange?: (teamId: string) => void;
  divisionId?: string;
};

export function MarketingTeamAnalyticsTables({
  teams,
  analytics,
  isLoading,
  teamId = "",
  onTeamIdChange,
  divisionId,
}: MarketingTeamAnalyticsTablesProps) {
  if (isLoading) {
    return (
      <div className="flex flex-col gap-4">
        <LoadingTeamGroupCard />
      </div>
    );
  }

  const viewModels =
    teams.length > 0
      ? teams.map(mapTeamBreakdown)
      : [buildFallbackTeamFromAnalytics(analytics)];

  const displayTeams = teamId
    ? viewModels.filter((team) => team.teamId === teamId)
    : viewModels;

  if (displayTeams.length === 0) {
    return (
      <div className="rounded-2xl border border-dashed border-gray-200 bg-white/40 px-6 py-12 text-center backdrop-blur-sm">
        <p className="font-['Lexend'] text-sm font-semibold text-[#1d1d39]">
          No data for the selected team
        </p>
        <p className="mt-1 text-xs text-gray-500 font-['Lexend_Deca']">
          Try clearing the team filter or choosing a different date range.
        </p>
      </div>
    );
  }

  const showTeamName = displayTeams.length > 1 || !teamId;

  return (
    <div className="flex flex-col gap-4">
      {onTeamIdChange ? (
        <div className="flex flex-wrap items-end justify-between gap-3 rounded-2xl border border-white/60 bg-white/50 px-4 py-3 backdrop-blur-xl">
          <div>
            <p className="text-xs font-semibold uppercase tracking-wide text-gray-500">
              Team scope
            </p>
            <p className="text-xs font-medium text-gray-600">
              Filter breakdown tables by sales team
            </p>
          </div>
          <div className="w-full min-w-[200px] sm:w-[220px]">
            <TeamSelect
              value={teamId}
              onValueChange={onTeamIdChange}
              divisionId={divisionId}
              allowEmpty
              emptyOptionLabel="All Teams"
              placeholder="All Teams"
              triggerClassName="h-11 rounded-xl bg-gray-50"
              aria-label="Filter by team"
            />
          </div>
        </div>
      ) : null}

      {displayTeams.map((team) => (
        <TeamAnalyticsGroupCard
          key={team.teamId}
          teamName={team.teamName}
          showTeamName={showTeamName}
        >
          <AnalyticsTableSection
            title="Account Executives"
            subtitle="Spending, leads, revenue & ROI by associate and channel"
          >
            <table className="w-full min-w-[1080px] border-collapse bg-white/40">
              <TableHead associateLabel="Associate" headers={AE_HEADERS} />
              <tbody>
                {team.aeAssociates.length === 0 ? (
                  <EmptyTableRow
                    colSpan={AE_HEADERS.length + 1}
                    message="No AE-assigned leads in this period."
                  />
                ) : (
                  team.aeAssociates.map((associate) => (
                    <AeAssociateRows
                      key={associate.userId}
                      associate={associate}
                    />
                  ))
                )}
                <AeOverallRows overall={team.aeOverall} />
              </tbody>
            </table>
          </AnalyticsTableSection>

          <AnalyticsTableSection
            title="Business Development"
            subtitle="Lead funnel & connectivity by associate and channel"
            className="border-t border-gray-100/80"
          >
            <table className="w-full min-w-[980px] border-collapse bg-white/40">
              <TableHead associateLabel="Associate" headers={BDR_HEADERS} />
              <tbody>
                {team.bdrAssociates.length === 0 ? (
                  <EmptyTableRow
                    colSpan={BDR_HEADERS.length + 1}
                    message="No BDRs on this team roster."
                  />
                ) : (
                  team.bdrAssociates.map((associate) => (
                    <BdrAssociateRows
                      key={associate.userId}
                      associate={associate}
                    />
                  ))
                )}
                <BdrOverallRow overall={team.bdrOverall} />
              </tbody>
            </table>
          </AnalyticsTableSection>
        </TeamAnalyticsGroupCard>
      ))}
    </div>
  );
}
