"use client";

import * as React from "react";
import { resolveCustomerTenant } from "@/app/customer/_lib/resolve-customer-tenant";
import Link from "next/link";
import { useParams } from "next/navigation";
import { Area, AreaChart } from "recharts";
import { BarChart3, Download, LineChart, RefreshCw, Sparkles, X } from "lucide-react";
import { toast } from "sonner";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import {
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
  type ChartConfig,
} from "@/components/ui/chart";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { cn } from "@/lib/utils";
import { getInitialAssetAnalyticsFilters } from "@/lib/report-user-settings";

import { AssetAnalyticsFiltersDialog } from "./asset-analytics-filters-dialog";
import { AssetAnalyticsMetricCard } from "./asset-analytics-metric-card";
import {
  type AssetAnalyticsAssetTab,
  type AssetAnalyticsFilters,
  defaultAssetAnalyticsFilters,
  hasActiveAssetAnalyticsFilters,
} from "./schema";
import { filterTickerGroups, groupMetrics, parseGainTone, sortAssetTabs } from "./utils";
import { useAssetAnalyticsList } from "../../_lib/use-asset-analytics-list";
import { useImpersonationScopeRefresh } from "@/app/customer/_lib/admin/use-impersonation-scope-refresh";

const chartConfig = { price: { label: "Price", color: "hsl(142 71% 45%)" } } satisfies ChartConfig;

const mockChartData = [
  { date: "Jan", price: 162 },
  { date: "Feb", price: 168 },
  { date: "Mar", price: 171 },
  { date: "Apr", price: 175 },
  { date: "May", price: 178 },
  { date: "Jun", price: 182 },
  { date: "Jul", price: 186 },
  { date: "Aug", price: 189 },
];

function segmentClass(active: boolean) {
  return cn(
    "h-8 shrink-0 rounded-md px-3 font-semibold text-xs transition-colors",
    active ? "bg-emerald-600 text-white shadow-sm" : "text-muted-foreground hover:bg-background/80 hover:text-foreground",
  );
}

function KpiTile({
  label,
  value,
  tone,
}: {
  label: string;
  value: string;
  tone?: "positive" | "negative" | "neutral";
}) {
  return (
    <div className="min-w-[140px] flex-1 rounded-lg border border-white/15 bg-white/10 px-4 py-3 backdrop-blur-sm">
      <p className="text-[10px] font-bold text-white/65 uppercase tracking-wider">{label}</p>
      <p
        className={cn(
          "mt-1 font-bold text-lg tabular-nums tracking-tight",
          tone === "positive" && "text-emerald-300",
          tone === "negative" && "text-red-300",
          !tone || tone === "neutral" ? "text-white" : "",
        )}
      >
        {value}
      </p>
    </div>
  );
}

function MetricsGrid({ tab }: { tab: AssetAnalyticsAssetTab }) {
  const sections = groupMetrics(tab.metrics);

  return (
    <div className="space-y-6">
      {sections.map((section) => (
        <div key={section.title}>
          <h4 className="mb-3 font-semibold text-muted-foreground text-xs uppercase tracking-wider">{section.title}</h4>
          <ul className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
            {section.items.map((item) => (
              <li key={item.label}>
                <AssetAnalyticsMetricCard
                  label={item.label}
                  value={item.value}
                  highlight={
                    item.label === "Gain /Loss %age"
                      ? parseGainTone(tab.metrics.gainLossPercent)
                      : item.label === "XIRR %age"
                        ? parseGainTone(tab.metrics.xirr)
                        : undefined
                  }
                />
              </li>
            ))}
          </ul>
        </div>
      ))}
    </div>
  );
}

function TickerSection({ group }: { group: ReturnType<typeof filterTickerGroups>[0] }) {
  const sortedTabs = sortAssetTabs(group.tabs);
  const graphTab = sortedTabs.find((t) => t.hasChart);
  const firstTabId = graphTab ? "graph" : sortedTabs[0]?.assetClass.toLowerCase().replace(/\s+/g, "-") ?? "";
  const [activeTab, setActiveTab] = React.useState(firstTabId);
  const [syncedTabKey, setSyncedTabKey] = React.useState(`${group.tickerId}|${firstTabId}`);
  const tabKey = `${group.tickerId}|${firstTabId}`;
  if (tabKey !== syncedTabKey) {
    setSyncedTabKey(tabKey);
    setActiveTab(firstTabId);
  }

  const displayTab =
    activeTab === "graph"
      ? null
      : sortedTabs.find((t) => t.assetClass.toLowerCase().replace(/\s+/g, "-") === activeTab) ?? sortedTabs[0] ?? null;

  const primaryTab = sortedTabs[0];
  const gainTone = primaryTab ? parseGainTone(primaryTab.metrics.gainLossPercent) : "neutral";

  return (
    <div className="space-y-4">
      <div className="overflow-hidden rounded-xl bg-gradient-to-br from-slate-800 via-slate-700 to-emerald-900/80 text-white shadow-lg">
        <div className="border-b border-white/10 px-5 py-4">
          <p className="font-mono text-emerald-200/90 text-xs uppercase tracking-wider">
            {primaryTab?.tickerDisplay ?? group.name.split(" ")[0]}
          </p>
          <h2 className="mt-1 font-semibold text-xl tracking-tight sm:text-2xl">{group.name}</h2>
          {primaryTab ? (
            <p className="mt-1 text-sm text-white/75">{primaryTab.productName}</p>
          ) : null}
        </div>
        {primaryTab ? (
          <div className="flex flex-wrap gap-3 p-4">
            <KpiTile label="Market value (USD)" value={primaryTab.metrics.totalMarketValueUsd} />
            <KpiTile label="XIRR" value={primaryTab.metrics.xirr} tone={parseGainTone(primaryTab.metrics.xirr)} />
            <KpiTile
              label="Gain / loss"
              value={primaryTab.metrics.gainLossPercent}
              tone={gainTone}
            />
            <KpiTile label="Quantity" value={primaryTab.metrics.totalQuantity} />
          </div>
        ) : null}
      </div>

      <div
        className="inline-flex max-w-full gap-0.5 overflow-x-auto rounded-lg border border-border/60 bg-muted/40 p-1"
        role="tablist"
      >
        {graphTab ? (
          <button type="button" role="tab" aria-selected={activeTab === "graph"} onClick={() => setActiveTab("graph")} className={segmentClass(activeTab === "graph")}>
            <span className="inline-flex items-center gap-1.5">
              <LineChart className="size-3.5" />
              Graph
            </span>
          </button>
        ) : null}
        {sortedTabs.map((tab) => {
          const id = tab.assetClass.toLowerCase().replace(/\s+/g, "-");
          return (
            <button
              key={id}
              type="button"
              role="tab"
              aria-selected={activeTab === id}
              onClick={() => setActiveTab(id)}
              className={segmentClass(activeTab === id)}
            >
              {tab.assetClass}
            </button>
          );
        })}
      </div>

      <Card className="border-border/80 shadow-sm">
        <CardContent className="p-4 sm:p-5">
          {activeTab === "graph" && graphTab ? (
            <div className="space-y-4">
              <div className="flex flex-wrap items-center justify-between gap-2">
                <div>
                  <p className="font-medium text-sm">Price chart</p>
                  <p className="text-muted-foreground text-xs">
                    Symbol <span className="font-mono">{graphTab.chartSymbol ?? graphTab.tickerCode}</span> · mock series until TradingView is connected
                  </p>
                </div>
                <Badge variant="secondary" className="font-normal text-[10px]">
                  Preview
                </Badge>
              </div>
              <ChartContainer config={chartConfig} className="aspect-[2.2/1] min-h-[280px] w-full">
                <AreaChart data={mockChartData} margin={{ left: 8, right: 8, top: 8, bottom: 0 }}>
                  <defs>
                    <linearGradient id="priceFill" x1="0" y1="0" x2="0" y2="1">
                      <stop offset="0%" stopColor="hsl(142 71% 45%)" stopOpacity={0.35} />
                      <stop offset="100%" stopColor="hsl(142 71% 45%)" stopOpacity={0} />
                    </linearGradient>
                  </defs>
                  <ChartTooltip content={<ChartTooltipContent />} />
                  <Area type="monotone" dataKey="price" stroke="hsl(142 71% 45%)" fill="url(#priceFill)" strokeWidth={2} />
                </AreaChart>
              </ChartContainer>
              <p className="text-muted-foreground text-xs">
                Switch to an asset class tab to view full metrics.
              </p>
            </div>
          ) : displayTab ? (
            <div className="space-y-6">
              <div className="flex flex-wrap items-start justify-between gap-3 rounded-lg border border-border/60 bg-muted/20 px-4 py-3">
                <div>
                  <p className="font-mono text-muted-foreground text-xs">{displayTab.tickerDisplay}</p>
                  <p className="font-semibold text-lg leading-tight">{displayTab.productName}</p>
                  <Badge variant="outline" className="mt-2 font-normal">
                    {displayTab.assetClass}
                  </Badge>
                </div>
                <div className="text-right">
                  <p className="text-muted-foreground text-xs">Market value</p>
                  <p className="font-semibold text-lg tabular-nums">{displayTab.metrics.totalMarketValueUsd}</p>
                  {displayTab.lotCount > 1 ? (
                    <p className="text-muted-foreground text-xs">{displayTab.lotCount} positions</p>
                  ) : null}
                </div>
              </div>

              <MetricsGrid tab={displayTab} />
            </div>
          ) : null}
        </CardContent>
      </Card>
    </div>
  );
}

export function AssetAnalyticsView() {
  const params = useParams<{ tenant?: string }>();
  const tenant = typeof params.tenant === "string" && params.tenant.trim() ? params.tenant.trim() : resolveCustomerTenant();
  // Defaults only — localStorage is applied in useEffect to keep SSR and hydration in sync.
  const [filters, setFilters] = React.useState<AssetAnalyticsFilters>(defaultAssetAnalyticsFilters);
  const [appliedFilters, setAppliedFilters] = React.useState<AssetAnalyticsFilters>(defaultAssetAnalyticsFilters);
  const [settingsReady, setSettingsReady] = React.useState(false);
  const [refreshKey, setRefreshKey] = React.useState(0);

  const refreshForPortfolioScope = React.useCallback(() => {
    setFilters(defaultAssetAnalyticsFilters);
    setAppliedFilters(defaultAssetAnalyticsFilters);
    setRefreshKey((value) => value + 1);
  }, []);
  useImpersonationScopeRefresh(refreshForPortfolioScope);


  React.useEffect(() => {
    const syncFromSettings = () => {
      const initial = getInitialAssetAnalyticsFilters();
      setFilters(initial);
      setAppliedFilters(initial);
      setSettingsReady(true);
    };
    syncFromSettings();
    window.addEventListener("report-settings-updated", syncFromSettings);
    return () => window.removeEventListener("report-settings-updated", syncFromSettings);
  }, []);

  const { groups, tickerOptions, bankOptions, assetClassOptions, isLoading, errorMessage } = useAssetAnalyticsList(
    appliedFilters.ticker,
    appliedFilters.banks,
    refreshKey,
    settingsReady,
  );

  const filteredGroups = React.useMemo(() => filterTickerGroups(groups, appliedFilters), [groups, appliedFilters]);

  const selectedTickerLabel = React.useMemo(() => {
    if (!appliedFilters.ticker) return null;
    const match = tickerOptions.find((option) => option.value === appliedFilters.ticker);
    if (!match || match.name === match.value) return appliedFilters.ticker;
    return `${match.name} · ${match.value}`;
  }, [appliedFilters.ticker, tickerOptions]);

  const hasActiveFilters = hasActiveAssetAnalyticsFilters(appliedFilters);
  const showResults = Boolean(appliedFilters.ticker) && filteredGroups.length > 0;

  const applyFilters = (next: AssetAnalyticsFilters) => {
    setFilters(next);
    setAppliedFilters(next);
    if (next.ticker) toast.success("Asset analytics loaded");
  };

  return (
    <div className="flex min-w-0 flex-col gap-5" key={refreshKey}>
      <div className="flex flex-col gap-3 border-b pb-4 lg:flex-row lg:items-start lg:justify-between">
        <div className="min-w-0 space-y-2">
          <div className="flex flex-wrap items-center gap-2.5">
            <div className="flex size-8 items-center justify-center rounded-lg border bg-violet-500/10 text-violet-700 dark:text-violet-400">
              <BarChart3 className="size-4" />
            </div>
            <h1 className="font-semibold text-2xl tracking-tight leading-none">Asset Analytics</h1>
            <Badge variant="secondary" className="gap-1 font-normal">
              <Sparkles className="size-3" />
              Beta
            </Badge>
            {selectedTickerLabel ? (
              <Badge variant="outline" className="max-w-[min(100%,280px)] truncate font-normal">
                {selectedTickerLabel}
              </Badge>
            ) : null}
            {isLoading ? (
              <Badge variant="outline" className="font-normal">
                Loading…
              </Badge>
            ) : null}
          </div>
          <p className="text-muted-foreground text-sm">
            Per-ticker metrics by asset class and custodian bank
            {hasActiveFilters ? " · filtered" : ""}
          </p>
          {errorMessage ? <p className="text-destructive text-sm">{errorMessage}</p> : null}
        </div>

        <div className="flex shrink-0 items-center gap-2">
          <AssetAnalyticsFiltersDialog
            filters={filters}
            onApply={applyFilters}
            tickerOptions={tickerOptions}
            bankOptions={bankOptions}
            assetClassOptions={assetClassOptions}
            isLoadingOptions={isLoading}
          />
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button variant="outline" size="icon" className="size-9 shrink-0">
                <Download className="size-4" />
                <span className="sr-only">Download</span>
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              <DropdownMenuItem onClick={() => toast.message("PDF export", { description: "Coming soon." })}>
                Download PDF
              </DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
          <Button
            variant="outline"
            size="icon"
            className="size-9 shrink-0"
            disabled={isLoading}
            onClick={() => {
              setRefreshKey((k) => k + 1);
              toast.success("Report refreshed");
            }}
          >
            <RefreshCw className={cn("size-4", isLoading && "animate-spin")} />
            <span className="sr-only">Refresh</span>
          </Button>
          <Button variant="outline" size="icon" className="size-9 shrink-0" asChild>
            <Link href="/customer/reports">
              <X className="size-4" />
              <span className="sr-only">Close</span>
            </Link>
          </Button>
        </div>
      </div>

      {!appliedFilters.ticker ? (
        <Card className="border-dashed">
          <CardHeader className="text-center">
            <CardTitle className="text-base">Pick a ticker to get started</CardTitle>
            <CardDescription>
              Use the filters button to search for an instrument, or set a default ticker in{" "}
              <Link
                href={`/customer/${tenant}/settings?section=asset-analytics`}
                className="text-primary underline-offset-4 hover:underline"
              >
                Settings
              </Link>
              .
            </CardDescription>
          </CardHeader>
        </Card>
      ) : !showResults && !isLoading ? (
        <Card className="border-dashed">
          <CardHeader className="text-center">
            <CardTitle className="text-base">No results</CardTitle>
            <CardDescription>
              No holdings for this ticker with the current asset class or bank filters. Broaden your selection and
              try again.
            </CardDescription>
          </CardHeader>
        </Card>
      ) : (
        filteredGroups.map((group) => <TickerSection key={group.tickerId} group={group} />)
      )}
    </div>
  );
}
