"use client";

import * as React from "react";
import Link from "next/link";
import { Search, X } from "lucide-react";

import { Button } from "@/components/ui/button";
import {
  Combobox,
  ComboboxContent,
  ComboboxEmpty,
  ComboboxInput,
  ComboboxItem,
  ComboboxList,
  ComboboxTrigger,
} from "@/components/ui/combobox";
import { InputGroupAddon } from "@/components/ui/input-group";
import { Label } from "@/components/ui/label";
import { cn } from "@/lib/utils";

import { useAssetAnalyticsList } from "@/app/customer/[tenant]/reports/asset-analytics/_lib/use-asset-analytics-list";
import type { AssetAnalyticsTickerOption } from "@/app/customer/[tenant]/reports/asset-analytics/_lib/map-asset-analytics-item";
import { assetAnalyticsReportHref } from "@/app/customer/[tenant]/reports/asset-analytics/_lib/asset-analytics-url";
import type { UserReportSettings } from "@/lib/report-user-settings";

import { SettingsSection } from "./settings-section";

/** The catalog holds ~1k instruments; render a slice and let typing narrow it. */
const MAX_VISIBLE_TICKERS = 150;

function tickerLabel(option: AssetAnalyticsTickerOption): string {
  return option.name !== option.value ? option.name : option.value;
}

function TickerCombobox({
  options,
  value,
  loading,
  onChange,
}: {
  options: AssetAnalyticsTickerOption[];
  value: string;
  loading: boolean;
  onChange: (value: string) => void;
}) {
  const [term, setTerm] = React.useState("");

  const selected = React.useMemo(() => {
    if (!value) return null;
    return options.find((option) => option.value === value) ?? { value, name: value };
  }, [options, value]);

  const filtered = React.useMemo(() => {
    const q = term.trim().toLowerCase();
    const list = q
      ? options.filter((option) => option.value.toLowerCase().includes(q) || option.name.toLowerCase().includes(q))
      : options;
    return list.slice(0, MAX_VISIBLE_TICKERS);
  }, [options, term]);

  const items = React.useMemo(
    () => (selected && !filtered.some((option) => option.value === selected.value) ? [selected, ...filtered] : filtered),
    [filtered, selected],
  );

  return (
    <div className="flex items-center gap-1">
      <Combobox
        items={options}
        filteredItems={items}
        filter={null}
        value={selected}
        onValueChange={(next) => {
          onChange(next?.value ?? "");
          setTerm("");
        }}
        onInputValueChange={(next) => setTerm(String(next ?? ""))}
        itemToStringLabel={(item) => `${item.name} ${item.value}`}
        isItemEqualToValue={(item, current) => item.value === current.value}
      >
        <ComboboxTrigger
          className={cn(
            "flex h-10 w-full min-w-0 items-center justify-between gap-2 rounded-md border border-input bg-background px-3 text-left text-sm outline-none",
            "hover:bg-accent/40 focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40",
            !selected && "text-muted-foreground",
          )}
          aria-label="Default ticker"
        >
          <span className="inline-flex min-w-0 flex-1 items-center gap-2">
            <Search className="size-3.5 shrink-0 text-muted-foreground" aria-hidden />
            {selected ? (
              <span className="min-w-0 truncate">
                {tickerLabel(selected)}
                {selected.name !== selected.value ? (
                  <span className="ml-1.5 font-mono text-muted-foreground text-xs">{selected.value}</span>
                ) : null}
              </span>
            ) : (
              <span className="truncate">{loading ? "Loading tickers…" : "Search by name or ISIN"}</span>
            )}
          </span>
        </ComboboxTrigger>
        <ComboboxContent
          side="bottom"
          sideOffset={4}
          align="start"
          className={cn(
            "w-(--anchor-width) min-w-[360px] overflow-hidden p-0",
            "*:data-[slot=input-group]:m-0 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-9",
            "*:data-[slot=input-group]:rounded-md *:data-[slot=input-group]:border-input",
            "*:data-[slot=input-group]:bg-background *:data-[slot=input-group]:shadow-none",
          )}
        >
          <div className="sticky top-0 z-10 border-b border-border/70 bg-muted/40 p-2">
            <ComboboxInput placeholder="Type a name or ISIN…" showTrigger={false} className="w-full bg-background">
              <InputGroupAddon align="inline-start">
                <Search className="size-3.5 text-muted-foreground" aria-hidden />
              </InputGroupAddon>
            </ComboboxInput>
          </div>
          <ComboboxEmpty>{loading ? "Loading tickers…" : "No ticker matches"}</ComboboxEmpty>
          <ComboboxList className="max-h-72 p-1">
            {(item: AssetAnalyticsTickerOption) => (
              <ComboboxItem key={item.value} value={item}>
                <span className="min-w-0">
                  <span className="block truncate">{tickerLabel(item)}</span>
                  {item.name !== item.value ? (
                    <span className="block truncate font-mono text-muted-foreground text-xs">{item.value}</span>
                  ) : null}
                </span>
              </ComboboxItem>
            )}
          </ComboboxList>
          {!term.trim() && options.length > MAX_VISIBLE_TICKERS ? (
            <p className="border-t border-border/60 px-3 py-2 text-muted-foreground text-xs">
              Showing {MAX_VISIBLE_TICKERS} of {options.length} — type to search the rest.
            </p>
          ) : null}
        </ComboboxContent>
      </Combobox>
      {value ? (
        <Button
          type="button"
          size="icon"
          variant="ghost"
          className="size-10 shrink-0 text-muted-foreground hover:text-foreground"
          aria-label="Clear default ticker"
          title="Clear"
          onClick={() => onChange("")}
        >
          <X className="size-4" />
        </Button>
      ) : null}
    </div>
  );
}

export function SettingsPanelAssetAnalytics({
  draft,
  onChange,
  tenant,
}: {
  draft: UserReportSettings;
  onChange: (patch: Partial<Pick<UserReportSettings, "defaultAnalyticsTicker">>) => void;
  tenant: string;
}) {
  const { tickerOptions, isLoading } = useAssetAnalyticsList("", []);
  const reportHref = assetAnalyticsReportHref(tenant, draft.defaultAnalyticsTicker);

  return (
    <div className="space-y-10">
      <SettingsSection
        title="Default ticker"
        description="Asset Analytics opens with this ticker loaded automatically — no search step required."
      >
        <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:max-w-3xl">
          <div className="space-y-2 sm:col-span-2">
            <Label className="text-xs font-medium text-muted-foreground">Ticker</Label>
            <TickerCombobox
              options={tickerOptions}
              value={draft.defaultAnalyticsTicker}
              loading={isLoading}
              onChange={(value) => onChange({ defaultAnalyticsTicker: value })}
            />
          </div>
        </div>
      </SettingsSection>

      <div className="flex flex-wrap items-center justify-between gap-4 rounded-xl border border-border/70 bg-muted/15 px-5 py-4">
        <div>
          <p className="font-medium text-sm">Preview report</p>
          <p className="mt-0.5 text-muted-foreground text-xs">Open Asset Analytics with the ticker selected above.</p>
        </div>
        <Button variant="outline" size="sm" asChild>
          <Link href={reportHref}>Open Asset Analytics</Link>
        </Button>
      </div>
    </div>
  );
}
