import { eventQueries } from "@/entities/event";
import { formatUsdt } from "@/shared/lib/money/usdt";
import { getCurrencySymbol } from "@/shared/lib/web3";
import { Loader } from "@/shared/ui/Loader";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/shared/ui/select";
import { useQuery } from "@tanstack/react-query";

export interface CategoryOption {
  categoryId: number;
  name: string;
  discount: number;
  quota: number;
  hasQuota: boolean;
  ticketsBought: number;
}

interface CategorySelectProps {
  eventId: number;
  ticketPrice: bigint;
  selectedCategoryId: number | null;
  onCategorySelect: (category: CategoryOption | null) => void;
}

export const CategorySelect: React.FC<CategorySelectProps> = ({
  eventId,
  ticketPrice,
  selectedCategoryId,
  onCategorySelect,
}) => {
  const { data: event, isLoading: isEventLoading } = useQuery(
    eventQueries.detail(eventId),
  );
  const { data: categories, isLoading } = useQuery(
    eventQueries.categories(eventId),
  );

  if (isLoading || isEventLoading) {
    return (
      <div className="flex items-center gap-2 py-3">
        <Loader />
        <span className="text-muted-foreground">Loading categories...</span>
      </div>
    );
  }

  if (!event || !categories || categories.length === 0) {
    return null;
  }

  const maxTickets = event.place.maxTickets;
  const globalRemaining = Math.max(
    0,
    maxTickets - Number(event.ticketsBought ?? 0),
  );

  const getCategoryPrice = (category: CategoryOption): bigint => {
    if (category.discount === 0) return ticketPrice;
    // Contract amounts are integer token units. Keep this integer to avoid validation issues.
    const discount = (ticketPrice * BigInt(category.discount)) / 10000n;
    return ticketPrice - discount;
  };

  const getRemainingQuota = (category: CategoryOption): number => {
    if (!category.hasQuota) return globalRemaining;
    const byQuota = category.quota - category.ticketsBought;
    return Math.max(0, Math.min(byQuota, globalRemaining));
  };

  const isSoldOut = (category: CategoryOption): boolean => {
    if (globalRemaining <= 0) return true;
    if (!category.hasQuota) return false;
    return category.ticketsBought >= category.quota;
  };

  const handleSelect = (value: string) => {
    const category = categories.find((c) => c.categoryId === Number(value));
    if (category) {
      onCategorySelect(category);
    }
  };

  const selectedCategory = selectedCategoryId
    ? categories.find((c) => c.categoryId === selectedCategoryId)
    : null;

  const finalPrice = selectedCategory
    ? getCategoryPrice(selectedCategory)
    : ticketPrice;

  return (
    <div className="space-y-3">
      <div>
        <label
          htmlFor="category-select"
          className="text-sm text-muted-foreground mb-1 block"
        >
          Select Ticket Category
        </label>
        <Select
          name="category-select"
          value={selectedCategoryId?.toString() ?? ""}
          onValueChange={handleSelect}
        >
          <SelectTrigger className="w-full">
            <SelectValue placeholder="Choose a category" />
          </SelectTrigger>
          <SelectContent>
            {categories.map((category) => {
              const remaining = getRemainingQuota(category);
              const soldOut = isSoldOut(category);
              const price = getCategoryPrice(category);
              const discountPercent = category.discount / 100;
              const discountLabel =
                discountPercent > 0 ? `-${discountPercent.toFixed(2)}%` : "";

              return (
                <SelectItem
                  key={category.categoryId}
                  value={category.categoryId.toString()}
                  disabled={soldOut}
                >
                  <div className="flex items-center justify-between w-full gap-4 text-sm">
                    <span className="font-medium">{category.name}</span>
                    <span className="text-green-500">{discountLabel}</span>
                    <span
                      className={category.discount > 0 ? "text-green-500" : ""}
                    >
                      {formatUsdt(price)}{" "}
                      <img
                        src={getCurrencySymbol()}
                        className="h-4 aspect-square inline"
                        alt="currency"
                      />
                    </span>
                    <span
                      className={
                        remaining < 5 ? "text-red-500" : "text-muted-foreground"
                      }
                    >
                      {`${remaining} left`}
                    </span>
                  </div>
                </SelectItem>
              );
            })}
          </SelectContent>
        </Select>
      </div>

      {selectedCategory && selectedCategory.discount > 0 && (
        <div className="flex justify-between items-center text-sm bg-green-500/10 p-2">
          <span className="text-green-600">You save:</span>
          <span className="text-green-600 font-medium">
            {formatUsdt(ticketPrice - finalPrice)}{" "}
            <img
              src={getCurrencySymbol()}
              className="h-4 aspect-square inline"
              alt="currency"
            />
          </span>
        </div>
      )}
    </div>
  );
};

Graph