import { memo, useCallback, useMemo } from "react";
import { Button } from "~/components/ui/button";
import { Badge } from "~/components/ui/badge";
import { Checkbox } from "~/components/ui/checkbox";
import { MiniDraftGrid } from "~/components/draft/MiniDraftGrid";
import {
  Popover,
  PopoverTrigger,
  PopoverContent,
} from "~/components/ui/popover";
import {
  Sheet,
  SheetTrigger,
  SheetContent,
  SheetTitle,
  SheetFooter,
  SheetClose,
} from "~/components/ui/sheet";
import { ListPlus, ListX, ChevronDown } from "lucide-react";

function getParticipantState(
  participant: { id: string; sport: { id: string } },
  draftedParticipantIds: Set<string>,
  queueMap: Map<string, string>,
  eligibility: {
    eligibleSportIds: Set<string>;
    ineligibleReasons: Record<string, string>;
  } | null
) {
  const isDrafted = draftedParticipantIds.has(participant.id);
  const isInQueue = queueMap.has(participant.id);
  const isEligible = eligibility
    ? eligibility.eligibleSportIds.has(participant.sport.id)
    : true;
  const ineligibleReason = eligibility?.ineligibleReasons[participant.sport.id];
  return { isDrafted, isInQueue, isEligible, ineligibleReason };
}

interface SportFilterContentProps {
  sportsForDropdown: Array<{ name: string; isDrafted: boolean }>;
  sportFilterSet: Set<string>;
  hideCompletedSports: boolean;
  hasTeam: boolean;
  variant: "sheet" | "popover";
  onToggleSport: (sport: string, checked: boolean | "indeterminate") => void;
  onHideCompletedSportsChange: (hide: boolean) => void;
}

function SportFilterContent({
  sportsForDropdown,
  sportFilterSet,
  hideCompletedSports,
  hasTeam,
  variant,
  onToggleSport,
  onHideCompletedSportsChange,
}: SportFilterContentProps) {
  const isSheet = variant === "sheet";
  const idPrefix = isSheet ? "sheet-sport-filter-" : "popover-sport-filter-";
  const listClass = isSheet
    ? "overflow-y-auto flex-1 px-4"
    : "max-h-64 overflow-y-auto p-2 space-y-0.5";
  const itemBaseClass = isSheet
    ? "flex items-center gap-4 py-4 border-b last:border-b-0 cursor-pointer text-base"
    : "flex items-center gap-2 px-2 py-2 rounded-sm hover:bg-accent cursor-pointer text-sm";
  const toggleLabelClass = isSheet
    ? "flex items-center gap-4 py-2 cursor-pointer text-base"
    : "flex items-center gap-2 px-4 py-3 cursor-pointer text-sm";

  return (
    <>
      <div className={listClass}>
        {sportsForDropdown
          .filter(({ isDrafted }) => !isDrafted || !hideCompletedSports)
          .map(({ name, isDrafted }) => {
            const checkboxId = `${idPrefix}${name.replace(/\s+/g, "-").toLowerCase()}`;
            return (
              <label
                key={name}
                htmlFor={checkboxId}
                className={`${itemBaseClass}${isDrafted ? " text-muted-foreground" : ""}`}
              >
                <Checkbox
                  id={checkboxId}
                  checked={sportFilterSet.has(name)}
                  onCheckedChange={(checked) => onToggleSport(name, checked)}
                />
                {name}
              </label>
            );
          })}
      </div>
      {hasTeam && (
        isSheet ? (
          <div className="px-4 border-t pt-3">
            <label className={toggleLabelClass}>
              <Checkbox
                checked={!hideCompletedSports}
                onCheckedChange={(checked) =>
                  onHideCompletedSportsChange(checked === false)
                }
              />
              <span>Show drafted sports</span>
            </label>
          </div>
        ) : (
          <>
            <hr className="mx-2 border-border" />
            <label className={toggleLabelClass}>
              <Checkbox
                checked={!hideCompletedSports}
                onCheckedChange={(checked) =>
                  onHideCompletedSportsChange(checked === false)
                }
              />
              <span>Show drafted sports</span>
            </label>
          </>
        )
      )}
    </>
  );
}

interface AvailableParticipantsSectionProps {
  participants: Array<{
    id: string;
    name: string;
    sport: {
      id: string;
      name: string;
    };
  }>;
  participantRanks: Map<string, { overallRank: number; sportRank: number }>;
  miniDraftGrid?: {
    draftSlots: Array<{
      id: string;
      draftOrder: number;
      team: { id: string; name: string; logoUrl?: string | null };
    }>;
    draftGrid: Array<
      Array<{
        pickNumber: number;
        round: number;
        pickInRound: number;
        teamId: string;
        pick?: {
          participant: { name: string };
          sport: { name: string };
        };
      }>
    >;
    currentPick: number;
    currentRound: number;
    ownerMap?: Record<string, string>;
    onForceAutopick?: (pickNumber: number, teamId: string) => void;
    onForceManualPickOpen?: (pickNumber: number, teamId: string) => void;
    onReplacePick?: (pickNumber: number, teamId: string) => void;
    onRollbackToPick?: (pickNumber: number) => void;
  };
  searchQuery: string;
  sportFilters: string[];
  hideDrafted: boolean;
  hideIneligible: boolean;
  hideCompletedSports: boolean;
  userDraftedSportNames: Set<string>;
  uniqueSports: string[];
  draftedParticipantIds: Set<string>;
  queue: Array<{ id: string; participantId: string }>;
  eligibility: {
    eligibleSportIds: Set<string>;
    ineligibleReasons: Record<string, string>;
  } | null;
  canPick: boolean;
  hasTeam: boolean;
  onSearchChange: (query: string) => void;
  onSportFiltersChange: (sports: string[]) => void;
  onHideDraftedChange: (hide: boolean) => void;
  onHideIneligibleChange: (hide: boolean) => void;
  onHideCompletedSportsChange: (hide: boolean) => void;
  onMakePick: (participantId: string) => void;
  onAddToQueue: (participantId: string) => void;
  onRemoveFromQueue: (queueId: string) => void;
}

export const AvailableParticipantsSection = memo(function AvailableParticipantsSection({
  participants,
  participantRanks,
  miniDraftGrid,
  searchQuery,
  sportFilters,
  hideDrafted,
  hideIneligible,
  hideCompletedSports,
  userDraftedSportNames,
  uniqueSports,
  draftedParticipantIds,
  queue,
  eligibility,
  canPick,
  hasTeam,
  onSearchChange,
  onSportFiltersChange,
  onHideDraftedChange,
  onHideIneligibleChange,
  onHideCompletedSportsChange,
  onMakePick,
  onAddToQueue,
  onRemoveFromQueue,
}: AvailableParticipantsSectionProps) {
  const queueMap = useMemo(
    () => new Map(queue.map((item) => [item.participantId, item.id])),
    [queue]
  );

  const sportFilterSet = useMemo(() => new Set(sportFilters), [sportFilters]);

  const sportsForDropdown = useMemo(() => {
    return uniqueSports.map((s) => ({
      name: s,
      isDrafted: hasTeam && userDraftedSportNames.has(s),
    }));
  }, [uniqueSports, userDraftedSportNames, hasTeam]);

  const triggerText = useMemo(
    () =>
      sportFilters.length === 0
        ? "All Sports"
        : sportFilters.length === 1
          ? sportFilters[0]
          : `${sportFilters.length} sports`,
    [sportFilters]
  );

  const triggerAriaLabel = useMemo(
    () =>
      sportFilters.length === 0
        ? "Filter by sport: All Sports"
        : sportFilters.length === 1
          ? `Filter by sport: ${sportFilters[0]}`
          : `Filter by sport: ${sportFilters.length} sports selected`,
    [sportFilters]
  );

  const handleToggleSport = useCallback(
    (sport: string, checked: boolean | "indeterminate") => {
      if (checked === true) {
        onSportFiltersChange([...sportFilters, sport]);
      } else {
        onSportFiltersChange(sportFilters.filter((s) => s !== sport));
      }
    },
    [sportFilters, onSportFiltersChange]
  );

  const handleReset = useCallback(() => {
    onSportFiltersChange([]);
    onHideCompletedSportsChange(false);
  }, [onSportFiltersChange, onHideCompletedSportsChange]);

  const emptyMessage = useMemo(() => {
    if (participants.length > 0) return null;
    const active: string[] = [];
    if (hideDrafted) active.push("drafted players");
    if (hideIneligible && eligibility) active.push("ineligible players");
    if (hideCompletedSports) active.push("drafted sports");
    if (sportFilters.length > 0) active.push("other sports");
    if (active.length === 0) return "No participants found.";
    return `No participants found. Try showing ${active.join(", ")}.`;
  }, [participants.length, hideDrafted, hideIneligible, hideCompletedSports, eligibility, sportFilters]);

  const hasActiveFilters = sportFilters.length > 0 || hideCompletedSports;

  return (
    <div className="flex flex-col h-full">
      {miniDraftGrid && (
        <div className="px-4 pt-4 pb-2 flex-shrink-0 border-b">
          <MiniDraftGrid {...miniDraftGrid} />
        </div>
      )}
      <div className="px-4 pt-4 pb-2 flex-shrink-0">
        <div className="space-y-2">
          {/* Search Input */}
          <input
            type="text"
            placeholder="Search participants..."
            value={searchQuery}
            onChange={(e) => onSearchChange(e.target.value)}
            className="w-full px-3 py-2 border rounded-md text-base md:text-sm bg-background text-foreground"
          />

          <div className="flex flex-wrap gap-2">
            {/* Sport Filter Multi-Select */}
            <div className="flex-1 min-w-[120px]">
              {/* Mobile: bottom sheet */}
              <div className="md:hidden">
                <Sheet>
                  <SheetTrigger asChild>
                    <Button
                      variant="outline"
                      aria-label={triggerAriaLabel}
                      className="w-full justify-between text-base font-normal"
                    >
                      <span className="truncate">{triggerText}</span>
                      <ChevronDown className="h-4 w-4 shrink-0 opacity-50" />
                    </Button>
                  </SheetTrigger>
                  <SheetContent side="bottom" className="max-h-[70vh] pt-12" aria-describedby={undefined}>
                    <SheetTitle className="sr-only">Filter by sport</SheetTitle>
                    <SportFilterContent
                      sportsForDropdown={sportsForDropdown}
                      sportFilterSet={sportFilterSet}
                      hideCompletedSports={hideCompletedSports}
                      hasTeam={hasTeam}
                      variant="sheet"
                      onToggleSport={handleToggleSport}
                      onHideCompletedSportsChange={onHideCompletedSportsChange}
                    />
                    <SheetFooter className="px-4 pb-8 flex-row gap-2">
                      {hasActiveFilters && (
                        <Button
                          variant="outline"
                          className="flex-1"
                          onClick={handleReset}
                        >
                          Reset
                        </Button>
                      )}
                      <SheetClose asChild>
                        <Button className="flex-1">Done</Button>
                      </SheetClose>
                    </SheetFooter>
                  </SheetContent>
                </Sheet>
              </div>

              {/* Desktop: popover */}
              <div className="hidden md:block">
                <Popover>
                  <PopoverTrigger asChild>
                    <Button
                      variant="outline"
                      aria-label={triggerAriaLabel}
                      className="w-full justify-between text-sm font-normal"
                    >
                      <span className="truncate">{triggerText}</span>
                      <ChevronDown className="h-4 w-4 shrink-0 opacity-50" />
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent className="w-72 p-0" align="start">
                    {hasActiveFilters && (
                      <div className="flex justify-end px-2 pt-2">
                        <Button
                          variant="ghost"
                          size="sm"
                          className="h-auto px-2 py-1 text-xs"
                          onClick={handleReset}
                        >
                          Reset
                        </Button>
                      </div>
                    )}
                    <SportFilterContent
                      sportsForDropdown={sportsForDropdown}
                      sportFilterSet={sportFilterSet}
                      hideCompletedSports={hideCompletedSports}
                      hasTeam={hasTeam}
                      variant="popover"
                      onToggleSport={handleToggleSport}
                      onHideCompletedSportsChange={onHideCompletedSportsChange}
                    />
                  </PopoverContent>
                </Popover>
              </div>
            </div>

            {/* Show/Hide Drafted Toggle */}
            <label className="flex items-center gap-2 text-sm cursor-pointer whitespace-nowrap px-3 py-2 border rounded-md">
              <Checkbox
                checked={!hideDrafted}
                onCheckedChange={(checked) => onHideDraftedChange(checked === false)}
              />
              <span>Show Drafted</span>
            </label>

            {/* Show/Hide Ineligible Toggle - only show if user has a team */}
            {hasTeam && eligibility && (
              <label className="flex items-center gap-2 text-sm cursor-pointer whitespace-nowrap px-3 py-2 border rounded-md">
                <Checkbox
                  checked={!hideIneligible}
                  onCheckedChange={(checked) => onHideIneligibleChange(checked === false)}
                />
                <span>Show Ineligible</span>
              </label>
            )}
          </div>

        </div>
      </div>

      {/* Mobile Card List - visible on mobile only */}
      <div className="flex md:hidden flex-1 overflow-y-auto flex-col gap-2 px-4 py-2">
        {participants.length === 0 ? (
          <div className="text-center py-8 text-muted-foreground text-sm">
            {emptyMessage}
          </div>
        ) : (
          participants.map((participant) => {
            const { isDrafted, isInQueue, isEligible, ineligibleReason } =
              getParticipantState(participant, draftedParticipantIds, queueMap, eligibility);

            return (
              <div
                key={participant.id}
                className={`bg-card border rounded-lg p-3 flex items-start justify-between gap-3 transition-colors ${
                  isDrafted
                    ? "bg-muted/50 opacity-60"
                    : !isEligible
                      ? "bg-destructive/10 opacity-75"
                      : ""
                }`}
              >
                <div className="flex flex-col gap-1 min-w-0">
                  <span
                    className={`font-semibold text-sm truncate ${!isEligible && !isDrafted ? "text-muted-foreground" : ""}`}
                  >
                    {participant.name}
                  </span>
                  <div className="flex flex-wrap gap-1 items-center">
                    <Badge variant="outline" className="text-xs">
                      {participant.sport.name}
                    </Badge>
                    <span className="text-xs text-muted-foreground tabular-nums">
                      OVR {participantRanks.get(participant.id)?.overallRank} · SPR {participantRanks.get(participant.id)?.sportRank}
                    </span>
                    {isDrafted && (
                      <Badge variant="secondary" className="text-xs">
                        Drafted
                      </Badge>
                    )}
                    {!isDrafted && !isEligible && (
                      <Badge
                        variant="destructive"
                        className="text-xs"
                        title={ineligibleReason}
                      >
                        Ineligible
                      </Badge>
                    )}
                    {isInQueue && !isDrafted && isEligible && (
                      <Badge variant="default" className="text-xs">
                        Queued
                      </Badge>
                    )}
                  </div>
                </div>
                {hasTeam && !isDrafted && (
                  <div className="flex gap-2 flex-shrink-0">
                    {!isInQueue ? (
                      <Button
                        variant="ghost"
                        size="sm"
                        className="min-h-[44px] min-w-[44px]"
                        onClick={() => onAddToQueue(participant.id)}
                        title={!isEligible ? ineligibleReason : "Add to queue"}
                        disabled={!isEligible}
                      >
                        <ListPlus className="h-4 w-4" />
                      </Button>
                    ) : (
                      <Button
                        variant="ghost"
                        size="sm"
                        className="min-h-[44px] min-w-[44px]"
                        onClick={() => {
                          const queueId = queueMap.get(participant.id);
                          if (queueId) onRemoveFromQueue(queueId);
                        }}
                        title="Remove from queue"
                      >
                        <ListX className="h-4 w-4" />
                      </Button>
                    )}
                    <Button
                      variant="default"
                      size="sm"
                      className="min-h-[44px]"
                      onClick={() => onMakePick(participant.id)}
                      disabled={!canPick || !isEligible}
                      title={
                        !canPick
                          ? "Not your turn"
                          : !isEligible
                            ? ineligibleReason
                            : undefined
                      }
                    >
                      Draft
                    </Button>
                  </div>
                )}
              </div>
            );
          })
        )}
      </div>

      {/* Desktop Table - hidden on mobile */}
      <div className="hidden md:flex flex-1 overflow-hidden">
        <div className="h-full w-full overflow-y-auto">
          <table className="w-full text-sm">
            <thead className="bg-muted sticky top-0">
              <tr>
                <th className="text-center p-3 px-0 font-semibold">OVR</th>
                <th className="text-center p-3 px-0 font-semibold">SPR</th>
                <th className="text-left p-3 font-semibold">Participant</th>
                <th className="text-left p-3 font-semibold">Sport</th>
                {hasTeam && (
                  <th className="text-right p-3 font-semibold">Queue</th>
                )}
              </tr>
            </thead>
            <tbody>
              {participants.length === 0 ? (
                <tr>
                  <td
                    colSpan={hasTeam ? 5 : 4}
                    className="text-center py-8 text-muted-foreground"
                  >
                    {emptyMessage}
                  </td>
                </tr>
              ) : (
                participants.map((participant) => {
                  const { isDrafted, isInQueue, isEligible, ineligibleReason } =
                    getParticipantState(participant, draftedParticipantIds, queueMap, eligibility);

                  return (
                    <tr
                      key={participant.id}
                      className={`border-t transition-colors ${
                        isDrafted
                          ? "bg-muted/50 opacity-60"
                          : !isEligible
                            ? "bg-destructive/10 opacity-75"
                            : "hover:bg-muted/50"
                      }`}
                      title={
                        !isEligible && !isDrafted ? ineligibleReason : undefined
                      }
                    >
                      <td className="p-3 px-0 text-center text-muted-foreground tabular-nums">
                        {participantRanks.get(participant.id)?.overallRank}
                      </td>
                      <td className="p-3 px-0 text-center text-muted-foreground tabular-nums">
                        {participantRanks.get(participant.id)?.sportRank}
                      </td>
                      <td className="p-3">
                        <div className="flex items-center gap-2">
                          <span
                            className={`font-medium ${!isEligible && !isDrafted ? "text-muted-foreground" : ""}`}
                          >
                            {participant.name}
                          </span>
                          {isDrafted && (
                            <Badge variant="secondary" className="text-xs">
                              Drafted
                            </Badge>
                          )}
                          {!isDrafted && !isEligible && (
                            <Badge
                              variant="destructive"
                              className="text-xs"
                              title={ineligibleReason}
                            >
                              Ineligible
                            </Badge>
                          )}
                          {isInQueue && !isDrafted && isEligible && (
                            <Badge variant="default" className="text-xs">
                              Queued
                            </Badge>
                          )}
                        </div>
                      </td>
                      <td className="p-3 text-muted-foreground">
                        {participant.sport.name}
                      </td>
                      {hasTeam && (
                        <td className="p-3 text-right">
                          <div className="flex gap-2 justify-end items-center">
                            {!isDrafted && (
                              <>
                                {/* Queue icon button */}
                                {!isInQueue ? (
                                  <Button
                                    variant="ghost"
                                    size="sm"
                                    onClick={() => onAddToQueue(participant.id)}
                                    title={
                                      !isEligible
                                        ? ineligibleReason
                                        : "Add to queue"
                                    }
                                    disabled={!isEligible}
                                  >
                                    <ListPlus className="h-4 w-4" />
                                  </Button>
                                ) : (
                                  <Button
                                    variant="ghost"
                                    size="sm"
                                    onClick={() => {
                                      const queueId = queueMap.get(participant.id);
                                      if (queueId) onRemoveFromQueue(queueId);
                                    }}
                                    title="Remove from queue"
                                  >
                                    <ListX className="h-4 w-4" />
                                  </Button>
                                )}
                                {/* Draft button - always visible, disabled when not your turn */}
                                <Button
                                  variant="default"
                                  size="sm"
                                  onClick={() => onMakePick(participant.id)}
                                  disabled={!canPick || !isEligible}
                                  title={
                                    !canPick
                                      ? "Not your turn"
                                      : !isEligible
                                        ? ineligibleReason
                                        : undefined
                                  }
                                >
                                  Draft
                                </Button>
                              </>
                            )}
                          </div>
                        </td>
                      )}
                    </tr>
                  );
                })
              )}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
});
