"use client";

import * as React from "react";
import { Check, Save } from "lucide-react";
import { toast } from "sonner";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";

import { loadDefaultLayoutSettings, saveDefaultLayoutSettings } from "../_lib/tenant-settings-api";
import type { DefaultLayoutSettingsData } from "../_lib/tenant-settings-server-api";
import { cn } from "@/lib/utils";
import { errorMessageOr, toastApiError } from "@/lib/toast-api-error";
import {
  dispatchDefaultLayoutChanged,
  normalizeTenantDefaultLayout,
} from "@/app/customer/_lib/default-layout";

const MODE_HELP: Record<string, string> = {
  default: "Holdings are grouped by asset class, e.g. Equities, Fixed Income and Funds.",
  macro: "Holdings are grouped by macro asset class, which is set up centrally by your administrator.",
  bridge: "Holdings are grouped by your own custom groups. Anything not assigned shows as Ungrouped.",
};

const APPLIES_TO = ["Consolidated holdings", "Asset allocation", "Bank-wise AUM", "Dashboard widget"];

/** Example groupings (illustrative values) so each layout shows how holdings are bucketed. */
const PREVIEW: Record<string, { heading: string; rows: { label: string; pct: number }[] }> = {
  default: {
    heading: "By asset class",
    rows: [
      { label: "Cash & FX", pct: 12 },
      { label: "Equities", pct: 34 },
      { label: "Fixed Income", pct: 28 },
      { label: "Funds", pct: 16 },
      { label: "Structured Products", pct: 10 },
    ],
  },
  macro: {
    heading: "By macro asset class",
    rows: [
      { label: "Equities", pct: 36 },
      { label: "Fixed Income", pct: 27 },
      { label: "Liquidity", pct: 15 },
      { label: "Alternative Investments", pct: 12 },
      { label: "Multi Asset Funds", pct: 10 },
    ],
  },
  bridge: {
    heading: "By your groups",
    rows: [
      { label: "Group 1", pct: 41 },
      { label: "Group 2", pct: 33 },
      { label: "Group 3", pct: 17 },
      { label: "Ungrouped", pct: 9 },
    ],
  },
};

const SEGMENT_SHADES = ["bg-primary", "bg-primary/75", "bg-primary/55", "bg-primary/40", "bg-primary/25"];

/** Mini grouped-allocation mock: a stacked bar plus one row per group. */
function LayoutPreview({ value }: { value: string }) {
  const preview = PREVIEW[value] ?? PREVIEW.default;
  return (
    <div className="space-y-2.5 p-3.5">
      <p className="font-medium text-[10px] text-muted-foreground uppercase tracking-wider">{preview.heading}</p>
      <div className="flex h-2 overflow-hidden rounded-full bg-muted">
        {preview.rows.map((row, index) => (
          <div
            key={row.label}
            className={SEGMENT_SHADES[index % SEGMENT_SHADES.length]}
            style={{ width: `${row.pct}%` }}
          />
        ))}
      </div>
      <ul className="space-y-1.5">
        {preview.rows.map((row, index) => (
          <li key={row.label} className="flex items-center gap-2 text-[11px] leading-none">
            <span className={cn("size-2 shrink-0 rounded-[3px]", SEGMENT_SHADES[index % SEGMENT_SHADES.length])} />
            <span className="min-w-0 flex-1 truncate">{row.label}</span>
            <span className="text-muted-foreground tabular-nums">{row.pct}%</span>
          </li>
        ))}
      </ul>
    </div>
  );
}

export function SettingsPanelDefaultLayout({ tenant }: { tenant: string }) {
  const [data, setData] = React.useState<DefaultLayoutSettingsData | null>(null);
  const [mode, setMode] = React.useState("default");
  const [loading, setLoading] = React.useState(true);
  const [saving, setSaving] = React.useState(false);
  const [error, setError] = React.useState<string | null>(null);

  React.useEffect(() => {
    let cancelled = false;
    void loadDefaultLayoutSettings(tenant)
      .then((result) => {
        if (cancelled) return;
        setData(result);
        setMode(normalizeTenantDefaultLayout(result.default_layout));
      })
      .catch((loadError) => {
        if (!cancelled) setError(errorMessageOr(loadError, "Default layout could not be loaded."));
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });
    return () => {
      cancelled = true;
    };
  }, [tenant]);

  async function save() {
    if (!mode) return;
    setSaving(true);
    try {
      const result = await saveDefaultLayoutSettings(tenant, mode);
      const saved = normalizeTenantDefaultLayout(result.default_layout);
      setData(result);
      setMode(saved);
      dispatchDefaultLayoutChanged(saved);
      toast.success("Default layout saved");
    } catch (saveError) {
      toastApiError(saveError, "Settings could not be saved.");
    } finally {
      setSaving(false);
    }
  }

  if (loading) return <p className="py-12 text-center text-muted-foreground text-sm">Loading Default layout…</p>;
  if (error || !data) {
    return (
      <p className="rounded-lg border border-destructive/30 bg-destructive/5 p-4 text-destructive text-sm">{error}</p>
    );
  }

  const modeOptions = Object.entries(data.modeOptions);
  const savedMode = normalizeTenantDefaultLayout(data.default_layout);
  const dirty = mode !== savedMode;

  return (
    <div className="space-y-6">
      <RadioGroup
        value={mode}
        onValueChange={setMode}
        disabled={data.isReadOnly}
        className="grid gap-4 sm:grid-cols-2 xl:grid-cols-3"
      >
        {modeOptions.map(([value, label]) => {
          const optionId = `default-layout-${value}`;
          const selected = mode === value;
          return (
            <label
              key={value}
              htmlFor={optionId}
              className={cn(
                "group relative flex cursor-pointer flex-col overflow-hidden rounded-xl border bg-card transition-all",
                "hover:border-primary/40 hover:shadow-sm has-focus-visible:ring-3 has-focus-visible:ring-ring/50",
                "has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-60",
                selected ? "border-primary shadow-sm ring-1 ring-primary" : "border-border/80",
              )}
            >
              <div
                className={cn(
                  "w-full border-b transition-colors",
                  selected ? "bg-primary/5" : "bg-muted/40 group-hover:bg-muted/60",
                )}
                aria-hidden="true"
              >
                <LayoutPreview value={value} />
              </div>
              <div className="flex items-start gap-3 p-4">
                <div className="min-w-0 flex-1 space-y-1">
                  <div className="flex flex-wrap items-center gap-2">
                    <Label htmlFor={optionId} className="cursor-pointer font-semibold text-sm">
                      {label}
                    </Label>
                    {value === savedMode ? (
                      <Badge variant="secondary" className="px-1.5 py-0 text-[10px] uppercase tracking-wide">
                        Current
                      </Badge>
                    ) : null}
                  </div>
                  <p className="text-muted-foreground text-xs leading-relaxed">{MODE_HELP[value] ?? ""}</p>
                </div>
                <span
                  className={cn(
                    "flex size-5 shrink-0 items-center justify-center rounded-full border transition-colors",
                    selected ? "border-primary bg-primary text-primary-foreground" : "border-input bg-background",
                  )}
                >
                  {selected ? <Check className="size-3" strokeWidth={3} /> : null}
                </span>
              </div>
              <RadioGroupItem id={optionId} value={value} className="sr-only" />
            </label>
          );
        })}
      </RadioGroup>

      <div className="space-y-2 rounded-lg border border-dashed bg-muted/30 px-4 py-3">
        <p className="font-medium text-muted-foreground text-xs uppercase tracking-wide">
          Applies to · previews use example figures
        </p>
        <div className="flex flex-wrap gap-1.5">
          {APPLIES_TO.map((item) => (
            <Badge key={item} variant="outline" className="font-normal">
              {item}
            </Badge>
          ))}
        </div>
      </div>

      <div className="flex flex-wrap items-center justify-between gap-3 border-t pt-4">
        <p className="text-muted-foreground text-xs">
          {data.isReadOnly
            ? "You have view-only access to this setting."
            : dirty
              ? "You have unsaved changes."
              : "Layout is saved for this tenant. Access is controlled by the Default layout settings permission."}
        </p>
        {!data.isReadOnly ? (
          <div className="flex items-center gap-2">
            {dirty ? (
              <Button variant="ghost" disabled={saving} onClick={() => setMode(savedMode)}>
                Reset
              </Button>
            ) : null}
            <Button className="gap-2" disabled={saving || !dirty} onClick={() => void save()}>
              <Save className="size-4" /> {saving ? "Saving…" : "Save changes"}
            </Button>
          </div>
        ) : null}
      </div>
    </div>
  );
}
