"use client";

import * as React from "react";
import { ChevronDown, ChevronRight } from "lucide-react";

import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";
import { attainmentBand, type AeReportMemberMetrics } from "@/lib/ae-report-metrics";
import type { AeReportDivision, AeReportMember, AeReportTeam } from "@/lib/ae-report-data";
import { formatAeCurrency, formatAePercent } from "./ae-report-format";

const BAND_BADGE_VARIANT: Record<ReturnType<typeof attainmentBand>, "default" | "secondary" | "destructive"> = {
  "on-track": "default",
  "at-risk": "secondary",
  behind: "destructive",
};

function PctBadge({ pct }: { pct: number }) {
  return (
    <Badge variant={BAND_BADGE_VARIANT[attainmentBand(pct)]} size="sm" className="tabular-nums">
      {formatAePercent(pct)}
    </Badge>
  );
}

type RowKind = "division" | "team" | "ae" | "support";

type TreeFilters = {
  search: string;
};

function memberMatchesFilters(member: AeReportMember, filters: TreeFilters): boolean {
  if (filters.search && !member.name.toLowerCase().includes(filters.search)) return false;
  return true;
}

function teamHasVisibleMembers(team: AeReportTeam, filters: TreeFilters): boolean {
  if (!filters.search) return true;
  return team.members.some((member) => memberMatchesFilters(member, filters));
}

function divisionHasVisibleMembers(division: AeReportDivision, filters: TreeFilters): boolean {
  if (!filters.search) return true;
  return division.teams.some((team) => teamHasVisibleMembers(team, filters));
}

function MetricCells({ metrics }: { metrics: AeReportMemberMetrics }) {
  return (
    <>
      <TableCell className="text-right">{formatAeCurrency(metrics.target1To15)}</TableCell>
      <TableCell className="text-right">{formatAeCurrency(metrics.achieved1To15)}</TableCell>
      <TableCell className="text-right"><PctBadge pct={metrics.pct1To15} /></TableCell>
      <TableCell className="text-right">{formatAeCurrency(metrics.lag1To15)}</TableCell>
      <TableCell className="text-right">{formatAeCurrency(metrics.target16To31)}</TableCell>
      <TableCell className="text-right">{formatAeCurrency(metrics.achieved16To31)}</TableCell>
      <TableCell className="text-right"><PctBadge pct={metrics.pct16To31} /></TableCell>
      <TableCell className="text-right">{formatAeCurrency(metrics.lag16To31)}</TableCell>
      <TableCell className="text-right font-semibold">{formatAeCurrency(metrics.monthTarget)}</TableCell>
      <TableCell className="text-right font-semibold">{formatAeCurrency(metrics.monthAchieved)}</TableCell>
      <TableCell className="text-right"><PctBadge pct={metrics.monthPct} /></TableCell>
      <TableCell className="text-right">{formatAeCurrency(metrics.monthLag)}</TableCell>
      <TableCell className="text-right">{formatAeCurrency(metrics.revenueRequiredPerDay)}</TableCell>
      <TableCell className="text-right">{formatAeCurrency(metrics.dailyAvgAchieved)}</TableCell>
      <TableCell className="text-right"><PctBadge pct={metrics.dailyAvgPct} /></TableCell>
    </>
  );
}

/** Solid (non-transparent) colors — the sticky first column needs full opacity or
 * cells scrolling underneath it horizontally show through. */
const ROW_BG: Record<RowKind, string> = {
  division: "bg-[#e3e4f4]",
  team: "bg-[#eef0fa]",
  ae: "bg-white",
  support: "bg-[#f6f7fb]",
};

const ROW_STYLES: Record<RowKind, string> = {
  division: cn(ROW_BG.division, "font-extrabold"),
  team: cn(ROW_BG.team, "font-bold"),
  ae: ROW_BG.ae,
  support: cn(ROW_BG.support, "text-muted-foreground"),
};

const ROW_INDENT: Record<RowKind, string> = {
  division: "pl-2",
  team: "pl-7",
  ae: "pl-12",
  support: "pl-[4.5rem]",
};

function TreeRow({
  rowKind,
  label,
  metrics,
  badge,
  expandable,
  expanded,
  onToggle,
  countLabel,
}: {
  rowKind: RowKind;
  label: React.ReactNode;
  metrics: AeReportMemberMetrics;
  badge?: React.ReactNode;
  expandable?: boolean;
  expanded?: boolean;
  onToggle?: () => void;
  countLabel?: string;
}) {
  return (
    <TableRow
      className={cn(ROW_STYLES[rowKind], expandable && "cursor-pointer")}
      onClick={expandable ? onToggle : undefined}
    >
      <TableCell className={cn(ROW_INDENT[rowKind], ROW_BG[rowKind], "sticky left-0 z-10")}>
        <div className="flex items-center gap-1.5 whitespace-nowrap">
          {expandable ? (
            expanded ? (
              <ChevronDown className="size-3.5 shrink-0 text-muted-foreground" />
            ) : (
              <ChevronRight className="size-3.5 shrink-0 text-muted-foreground" />
            )
          ) : (
            <span className="inline-block size-3.5 shrink-0" />
          )}
          <span>{label}</span>
          {badge}
          {countLabel ? (
            <span className="text-[11px] font-normal text-muted-foreground">{countLabel}</span>
          ) : null}
        </div>
      </TableCell>
      <MetricCells metrics={metrics} />
    </TableRow>
  );
}

export type AeReportTreeProps = {
  divisions: AeReportDivision[];
  search: string;
};

export function AeReportTree({ divisions, search }: AeReportTreeProps) {
  const filters: TreeFilters = {
    search: search.trim().toLowerCase(),
  };
  const filtersActive = Boolean(filters.search);

  const [expandedDivisions, setExpandedDivisions] = React.useState<Set<string>>(new Set());
  const [expandedTeams, setExpandedTeams] = React.useState<Set<string>>(new Set());
  const [expandedMembers, setExpandedMembers] = React.useState<Set<string>>(new Set());

  const toggle = (set: Set<string>, setter: (next: Set<string>) => void, id: string) => {
    const next = new Set(set);
    if (next.has(id)) next.delete(id);
    else next.add(id);
    setter(next);
  };

  const visibleDivisions = divisions.filter((division) => divisionHasVisibleMembers(division, filters));

  if (!visibleDivisions.length) {
    return (
      <div className="flex min-h-[200px] w-full items-center justify-center rounded-[14px] border border-dashed border-muted-foreground/30 text-[13px] text-muted-foreground font-medium font-['Lexend_Deca']">
        No results match your filters.
      </div>
    );
  }

  return (
    <div className="overflow-x-auto rounded-[14px] border border-white bg-[rgba(244,246,255,0.4)] backdrop-blur-[15px]">
      <Table>
        <TableHeader>
          <TableRow>
            <TableHead className="sticky left-0 z-20 bg-[#f4f6ff] min-w-[220px]">Division / Team / AE</TableHead>
            <TableHead className="text-right">Target 1-15</TableHead>
            <TableHead className="text-right">Ach 1-15</TableHead>
            <TableHead className="text-right">% 1-15</TableHead>
            <TableHead className="text-right">Lag 1-15</TableHead>
            <TableHead className="text-right">Target 16-31</TableHead>
            <TableHead className="text-right">Ach 16-31</TableHead>
            <TableHead className="text-right">% 16-31</TableHead>
            <TableHead className="text-right">Lag 16-31</TableHead>
            <TableHead className="text-right">Monthly Target</TableHead>
            <TableHead className="text-right">Monthly Ach</TableHead>
            <TableHead className="text-right">Monthly %</TableHead>
            <TableHead className="text-right">Monthly Lag</TableHead>
            <TableHead className="text-right">Rev Req/Day</TableHead>
            <TableHead className="text-right">Daily Avg</TableHead>
            <TableHead className="text-right">Daily Avg %</TableHead>
          </TableRow>
        </TableHeader>
        <TableBody>
          {visibleDivisions.map((division) => {
            const divisionExpanded = filtersActive || expandedDivisions.has(division.divisionId);
            const visibleTeams = division.teams.filter((team) => teamHasVisibleMembers(team, filters));

            return (
              <React.Fragment key={division.divisionId}>
                <TreeRow
                  rowKind="division"
                  label={division.divisionName}
                  metrics={division.metrics}
                  expandable
                  expanded={divisionExpanded}
                  onToggle={() => toggle(expandedDivisions, setExpandedDivisions, division.divisionId)}
                  countLabel={`${division.teams.length} ${division.teams.length === 1 ? "team" : "teams"}`}
                />

                {divisionExpanded
                  ? visibleTeams.map((team) => {
                      const teamExpanded = filtersActive || expandedTeams.has(team.teamId);
                      const visibleMembers = team.members.filter((member) =>
                        memberMatchesFilters(member, filters),
                      );

                      return (
                        <React.Fragment key={team.teamId}>
                          <TreeRow
                            rowKind="team"
                            label={team.teamName}
                            metrics={team.metrics}
                            expandable
                            expanded={teamExpanded}
                            onToggle={() => toggle(expandedTeams, setExpandedTeams, team.teamId)}
                            countLabel={`${team.members.length} ${team.members.length === 1 ? "AE" : "AEs"}`}
                          />

                          {teamExpanded
                            ? visibleMembers.map((member) => {
                                const hasSupport = member.supportMembers.length > 0;
                                const memberExpanded =
                                  hasSupport && expandedMembers.has(member.userId);

                                return (
                                  <React.Fragment key={member.userId}>
                                    <TreeRow
                                      rowKind="ae"
                                      label={member.name}
                                      metrics={member.metrics}
                                      expandable={hasSupport}
                                      expanded={memberExpanded}
                                      onToggle={() =>
                                        toggle(expandedMembers, setExpandedMembers, member.userId)
                                      }
                                      badge={
                                        member.isTeamLead ? (
                                          <Badge variant="soft" size="sm">
                                            Lead
                                          </Badge>
                                        ) : undefined
                                      }
                                    />

                                    {memberExpanded
                                      ? member.supportMembers.map((support) => (
                                          <TreeRow
                                            key={support.assignmentId}
                                            rowKind="support"
                                            label={support.name}
                                            badge={
                                              support.supportRole ? (
                                                <Badge variant="outline" size="sm">
                                                  {support.supportRole}
                                                </Badge>
                                              ) : undefined
                                            }
                                            metrics={{
                                              target1To15: 0,
                                              achieved1To15: 0,
                                              pct1To15: 0,
                                              lag1To15: 0,
                                              target16To31: 0,
                                              achieved16To31: 0,
                                              pct16To31: 0,
                                              lag16To31: 0,
                                              monthTarget: support.target,
                                              monthAchieved: support.attained,
                                              monthPct: support.pct,
                                              monthLag: Math.max(0, support.target - support.attained),
                                              revenueRequiredPerDay: 0,
                                              dailyAvgAchieved: 0,
                                              dailyAvgPct: 0,
                                              estimatedRevenue: 0,
                                            }}
                                          />
                                        ))
                                      : null}
                                  </React.Fragment>
                                );
                              })
                            : null}
                        </React.Fragment>
                      );
                    })
                  : null}
              </React.Fragment>
            );
          })}
        </TableBody>
      </Table>
    </div>
  );
}
