import { useState } from "react";
import { ChevronDown, ChevronRight, Database, Loader2, Route, Wrench } from "lucide-react";
import type { Observability, ObservabilityDataUsed } from "@/services/agenticApi";
import { formatDateTime } from "./utils";

interface MessageTraceabilityProps {
  observability?: Observability | null;
  loading?: boolean;
  error?: string | null;
  sources?: unknown[];
}

function renderUnknown(value: unknown) {
  if (value == null) return "-";
  if (typeof value === "string") return value;
  try {
    return JSON.stringify(value, null, 2);
  } catch {
    return String(value);
  }
}

function sourceLabel(source: unknown, index: number) {
  if (source && typeof source === "object") {
    const record = source as Record<string, unknown>;
    return String(record.name ?? record.title ?? record.source ?? record.source_id ?? record.id ?? `Source ${index + 1}`);
  }
  return String(source ?? `Source ${index + 1}`);
}

function DataUsedCard({ item, index }: { item: ObservabilityDataUsed; index: number }) {
  return (
    <div className="rounded-md border border-slate-200 bg-white p-2">
      <div className="flex items-center justify-between gap-2">
        <p className="font-medium text-slate-900">{item.source?.name ?? `Data source ${index + 1}`}</p>
        {item.source?.type && <span className="rounded bg-slate-100 px-1.5 py-0.5 text-[10px] uppercase text-slate-500">{item.source.type}</span>}
      </div>

      {item.tables && item.tables.length > 0 && (
        <p className="mt-1.5 text-slate-600">
          Tables: {item.tables.map((table) => table.name).join(", ")}
        </p>
      )}

      {item.columns_read && item.columns_read.length > 0 && (
        <div className="mt-1.5 flex flex-wrap gap-1">
          {item.columns_read.map((column) => (
            <span key={column.id} className="rounded border border-slate-200 bg-slate-50 px-1.5 py-0.5 text-[11px] text-slate-600">
              {column.table ? `${column.table}.${column.name}` : column.name}
            </span>
          ))}
        </div>
      )}

      {item.group_by && item.group_by.length > 0 && (
        <p className="mt-1.5 text-slate-600">Grouped by: {item.group_by.join(", ")}</p>
      )}

      {typeof item.rows_returned === "number" && (
        <p className="mt-1.5 text-slate-600">Rows returned: {item.rows_returned}</p>
      )}

      {item.query && (
        <pre className="mt-2 max-h-40 overflow-auto rounded bg-slate-950 p-2 text-[11px] leading-4 text-slate-100">{item.query}</pre>
      )}
    </div>
  );
}

export function MessageTraceability({ observability, loading, error, sources = [] }: MessageTraceabilityProps) {
  const [open, setOpen] = useState(false);
  const [detailsOpen, setDetailsOpen] = useState(false);
  const traceSources = observability?.sources?.length ? observability.sources : sources;
  const hasTrace = Boolean(observability || loading || error || traceSources.length > 0);

  if (!hasTrace) return null;

  const toolCalls = observability?.tool_calls ?? [];
  const dataUsed = observability?.data_used ?? [];

  return (
    <div className="mt-3 border-t border-slate-200 pt-3">
      <button
        type="button"
        title="Show traceability for this AI answer"
        aria-expanded={open}
        onClick={() => setOpen((current) => !current)}
        className="inline-flex items-center gap-2 rounded-md px-2 py-1 text-xs font-medium text-slate-600 hover:bg-slate-100 hover:text-slate-950"
      >
        {open ? <ChevronDown className="h-3.5 w-3.5" /> : <ChevronRight className="h-3.5 w-3.5" />}
        Traceability
        {loading && <Loader2 className="h-3.5 w-3.5 animate-spin" />}
      </button>

      {open && (
        <div className="mt-3 space-y-3 rounded-md border border-slate-200 bg-slate-50 p-3 text-xs text-slate-700">
          {loading && <p className="text-slate-500">Traceability is being prepared.</p>}
          {error && <p className="text-red-600">{error}</p>}

          {observability?.generated_at && (
            <p className="text-[11px] uppercase tracking-wide text-slate-400">Generated {formatDateTime(observability.generated_at)}</p>
          )}

          {observability?.intent && (
            <div>
              <p className="font-semibold text-slate-900">Intent</p>
              <p className="mt-1 leading-5">{observability.intent}</p>
            </div>
          )}

          {(observability?.planning || observability?.thinking) && (
            <div className="space-y-2">
              <div className="flex items-center gap-2 font-semibold text-slate-900">
                <Route className="h-3.5 w-3.5" />
                Thought and planning
              </div>
              {observability.thinking && <p className="leading-5">{observability.thinking}</p>}
              {observability.planning?.goal_restated && <p className="leading-5">{observability.planning.goal_restated}</p>}
              {observability.planning?.assumptions && observability.planning.assumptions.length > 0 && (
                <ul className="list-disc space-y-1 pl-4">
                  {observability.planning.assumptions.map((item) => <li key={item}>{item}</li>)}
                </ul>
              )}
              {observability.planning?.steps && observability.planning.steps.length > 0 && (
                <div className="space-y-1">
                  {observability.planning.steps.map((step, index) => (
                    <div key={`${step.stage ?? "step"}-${index}`} className="rounded border border-slate-200 bg-white px-2 py-1.5">
                      <p className="font-medium text-slate-800">{step.stage ?? `Step ${step.step ?? index + 1}`}</p>
                      {step.objective && <p className="mt-0.5 text-slate-600">{step.objective}</p>}
                    </div>
                  ))}
                </div>
              )}
            </div>
          )}

          <div>
            <div className="flex items-center gap-2 font-semibold text-slate-900">
              <Database className="h-3.5 w-3.5" />
              Data used
            </div>
            {dataUsed.length === 0 ? (
              <p className="mt-1 text-slate-500">No data usage recorded for this answer.</p>
            ) : (
              <div className="mt-2 space-y-2">
                {dataUsed.map((item, index) => (
                  <DataUsedCard key={`${item.source?.id ?? "source"}-${index}`} item={item} index={index} />
                ))}
              </div>
            )}
          </div>

          <div>
            <button
              type="button"
              title="Show tool call details"
              aria-expanded={detailsOpen}
              onClick={() => setDetailsOpen((current) => !current)}
              className="inline-flex items-center gap-2 rounded-md px-1.5 py-1 text-xs font-semibold text-slate-900 hover:bg-slate-100"
            >
              {detailsOpen ? <ChevronDown className="h-3.5 w-3.5" /> : <ChevronRight className="h-3.5 w-3.5" />}
              <Wrench className="h-3.5 w-3.5" />
              Details
            </button>

            {detailsOpen && (
              toolCalls.length === 0 ? (
                <p className="mt-1 pl-1.5 text-slate-500">No tool call recorded for this answer.</p>
              ) : (
                <div className="mt-2 space-y-2 pl-1.5">
                  {toolCalls.map((tool, index) => (
                    <div key={`${tool.name}-${index}`} className="rounded-md border border-slate-200 bg-white p-2">
                      <div className="flex items-center justify-between gap-2">
                        <p className="font-medium text-slate-900">{tool.name}</p>
                        {tool.status && <span className="rounded bg-slate-100 px-1.5 py-0.5 text-[10px] uppercase text-slate-500">{tool.status}</span>}
                      </div>
                      {tool.summary && <p className="mt-1 text-slate-600">{tool.summary}</p>}
                      {tool.input !== undefined && (
                        <pre className="mt-2 max-h-40 overflow-auto rounded bg-slate-950 p-2 text-[11px] leading-4 text-slate-100">{renderUnknown(tool.input)}</pre>
                      )}
                      {tool.output !== undefined && (
                        <pre className="mt-2 max-h-40 overflow-auto rounded bg-white p-2 text-[11px] leading-4 text-slate-600 ring-1 ring-slate-200">{renderUnknown(tool.output)}</pre>
                      )}
                      {tool.error && <p className="mt-2 text-red-600">{tool.error}</p>}
                    </div>
                  ))}
                </div>
              )
            )}
          </div>

          {traceSources.length > 0 && (
            <div>
              <p className="font-semibold text-slate-900">Citations and sources</p>
              <div className="mt-2 flex flex-wrap gap-1.5">
                {traceSources.map((source, index) => (
                  <span key={`${sourceLabel(source, index)}-${index}`} className="rounded-md border border-slate-200 bg-white px-2 py-1 text-[11px] text-slate-600">
                    {sourceLabel(source, index)}
                  </span>
                ))}
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}
