import * as React from "react";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import type { HardwareDatabaseRow, SelectOption } from "@/types/local-frontier";

export type HardwareDatabaseProps = {
  rows: readonly HardwareDatabaseRow[];
  producers: readonly SelectOption[];
  priceBands: readonly SelectOption[];
};

function matchesRow(
  row: HardwareDatabaseRow,
  search: string,
  producer: string,
  priceBand: string,
): boolean {
  const query = search.trim().toLowerCase();
  return (
    (!query || row.searchText.includes(query)) &&
    (producer === "all" || row.acceleratorVendorKey === producer) &&
    (priceBand === "all" || row.priceBand === priceBand)
  );
}

function FilterSelect({
  label,
  value,
  options,
  onValueChange,
}: {
  label: string;
  value: string;
  options: readonly SelectOption[];
  onValueChange: (value: string) => void;
}): React.JSX.Element {
  return (
    <label className="grid gap-1.5">
      <span className="text-xs font-semibold text-muted-foreground">
        {label}
      </span>
      <Select value={value} onValueChange={onValueChange}>
        <SelectTrigger>
          <SelectValue />
        </SelectTrigger>
        <SelectContent>
          {options.map((option) => (
            <SelectItem key={option.value} value={option.value}>
              {option.label}
            </SelectItem>
          ))}
        </SelectContent>
      </Select>
    </label>
  );
}

function HardwareRow({ row }: { row: HardwareDatabaseRow }): React.JSX.Element {
  return (
    <TableRow>
      <TableCell>
        <a
          className="font-semibold text-foreground underline-offset-2 hover:underline"
          href={row.deviceHref}
        >
          {row.name}
        </a>
        <span className="mt-1 inline-flex border border-border px-2 py-0.5 text-xs">
          {row.kind}
        </span>
      </TableCell>
      <TableCell>
        <a
          className="text-foreground underline-offset-2 hover:underline"
          href={row.systemVendorHref}
        >
          {row.systemVendor}
        </a>
      </TableCell>
      <TableCell>
        <a
          className="text-foreground underline-offset-2 hover:underline"
          href={row.acceleratorVendorHref}
        >
          {row.acceleratorVendor}
        </a>
      </TableCell>
      <TableCell>
        <span>{row.memory}</span>
        <span className="ml-1 inline-flex border border-border px-1.5 py-0.5 text-xs">
          {row.memorySymbol}
        </span>
        <span className="block">{row.memoryType}</span>
      </TableCell>
      <TableCell>{row.bandwidth}</TableCell>
      <TableCell>
        {row.latestPrice}
        {row.estimated ? (
          <span title="Estimated or reconstructed price"> ≈</span>
        ) : null}
      </TableCell>
      <TableCell>{row.priceBandLabel}</TableCell>
      <TableCell>
        <span>{row.evidence}</span>
        <span className="mt-1 block text-xs">{row.confidence}</span>
      </TableCell>
    </TableRow>
  );
}

function HardwareTable({
  rows,
}: {
  rows: readonly HardwareDatabaseRow[];
}): React.JSX.Element {
  if (!rows.length) {
    return (
      <div className="p-8 text-muted-foreground">
        No devices match the current filters.
      </div>
    );
  }

  return (
    <Table className="min-w-[1120px]">
      <TableHeader>
        <TableRow>
          <TableHead>Device</TableHead>
          <TableHead>System vendor</TableHead>
          <TableHead>Accelerator vendor</TableHead>
          <TableHead>Memory</TableHead>
          <TableHead>Bandwidth</TableHead>
          <TableHead>Latest price</TableHead>
          <TableHead>Price band</TableHead>
          <TableHead>Evidence</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {rows.map((row) => (
          <HardwareRow key={row.id} row={row} />
        ))}
      </TableBody>
    </Table>
  );
}

export function HardwareDatabase({
  rows,
  producers,
  priceBands,
}: HardwareDatabaseProps): React.JSX.Element {
  const [search, setSearch] = React.useState("");
  const [producer, setProducer] = React.useState("all");
  const [priceBand, setPriceBand] = React.useState("all");
  const filteredRows = rows.filter((row) =>
    matchesRow(row, search, producer, priceBand),
  );

  return (
    <Card>
      <CardContent className="grid gap-4 p-0">
        <div className="grid grid-cols-[minmax(0,1fr)_minmax(12rem,16rem)_minmax(12rem,16rem)] gap-3 p-4 max-[980px]:grid-cols-1">
          <label className="grid gap-1.5">
            <span className="text-xs font-semibold text-muted-foreground">
              Search
            </span>
            <Input
              placeholder="Mac Studio, DGX, W7900, 128GB"
              type="search"
              value={search}
              onChange={(event) => {
                setSearch(event.currentTarget.value);
              }}
            />
          </label>
          <FilterSelect
            label="Accelerator vendor"
            options={producers}
            value={producer}
            onValueChange={setProducer}
          />
          <FilterSelect
            label="Price band"
            options={priceBands}
            value={priceBand}
            onValueChange={setPriceBand}
          />
        </div>
        <HardwareTable rows={filteredRows} />
      </CardContent>
    </Card>
  );
}
