"use client";

import { useState } from "react";
import Link from "next/link";
import type { Route } from "next";
import { trpc } from "~/lib/trpc/client.js";

// ─── Anomaly type badge colors ───────────────────────────────────────────────

const SEVERITY_STYLES = {
  critical: "bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-300",
  warning: "bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-300",
} as const;

const TYPE_LABELS: Record<string, string> = {
  budget: "Budget",
  staffing: "Staffing",
  utilization: "Utilization",
  timeline: "Timeline",
};

const TYPE_ICONS: Record<string, string> = {
  budget: "\u20AC",      // Euro sign
  staffing: "\u2642",    // Person sign
  utilization: "\u2B24", // Circle
  timeline: "\u23F0",    // Clock
};

// ─── Shimmer skeleton ────────────────────────────────────────────────────────

function Shimmer({ className = "" }: { className?: string }) {
  return (
    <div
      className={`animate-pulse rounded bg-gray-200 dark:bg-slate-700 ${className}`}
    />
  );
}

function AnomalyListSkeleton() {
  return (
    <div className="space-y-3">
      {Array.from({ length: 4 }).map((_, i) => (
        <div key={i} className="flex items-start gap-3 rounded-xl border border-gray-100 p-4 dark:border-slate-800">
          <Shimmer className="h-6 w-16 rounded-full" />
          <div className="flex-1 space-y-2">
            <Shimmer className="h-4 w-3/4" />
            <Shimmer className="h-3 w-1/2" />
          </div>
        </div>
      ))}
    </div>
  );
}

function NarrativeSkeleton() {
  return (
    <div className="space-y-3">
      <Shimmer className="h-4 w-full" />
      <Shimmer className="h-4 w-5/6" />
      <Shimmer className="h-4 w-4/6" />
      <Shimmer className="h-4 w-3/4" />
    </div>
  );
}

// ─── Entity link helper ──────────────────────────────────────────────────────

function entityLink(type: string, entityId: string): string {
  if (type === "utilization") return `/resources/${entityId}`;
  return `/projects/${entityId}`;
}

type ProjectOption = {
  id: string;
  name: string;
  shortCode: string | null;
};

// ─── Main component ──────────────────────────────────────────────────────────

export function InsightsPanel() {
  const [selectedProjectId, setSelectedProjectId] = useState<string>("");
  const [narrativeFilter, setNarrativeFilter] = useState<string | null>(null);

  // Fetch anomalies
  const anomaliesQuery = trpc.insights.detectAnomalies.useQuery(undefined, {
    staleTime: 60_000,
    refetchOnWindowFocus: false,
  });

  // Fetch AI configuration status
  const aiConfigQuery = trpc.settings.getAiConfigured.useQuery(undefined, {
    staleTime: 300_000,
  });

  // Fetch project list for dropdown
  const projectsQuery = trpc.project.list.useQuery(
    { page: 1, limit: 200 },
    { staleTime: 60_000, refetchOnWindowFocus: false },
  );

  // Fetch cached narrative for selected project
  const cachedNarrativeQuery = trpc.insights.getCachedNarrative.useQuery(
    { projectId: selectedProjectId },
    {
      enabled: !!selectedProjectId,
      staleTime: 30_000,
    },
  );

  // Generate narrative mutation
  const generateMutation = trpc.insights.generateProjectNarrative.useMutation({
    onSuccess: () => {
      // Refetch the cached narrative
      void cachedNarrativeQuery.refetch();
    },
  });

  const anomalies = anomaliesQuery.data ?? [];
  const projects: ProjectOption[] = (projectsQuery.data?.projects ?? []) as ProjectOption[];

  // Filter anomalies
  const filteredAnomalies = narrativeFilter
    ? anomalies.filter((a) => a.type === narrativeFilter)
    : anomalies;

  const summaryCountsByType = anomalies.reduce(
    (acc, a) => {
      acc[a.type] = (acc[a.type] ?? 0) + 1;
      return acc;
    },
    {} as Record<string, number>,
  );

  const criticalCount = anomalies.filter((a) => a.severity === "critical").length;

  return (
    <div className="space-y-8">
      {/* ── Summary cards ─────────────────────────────────────────────── */}
      <div className="grid grid-cols-2 gap-4 sm:grid-cols-4">
        {(["budget", "staffing", "utilization", "timeline"] as const).map((type) => {
          const count = summaryCountsByType[type] ?? 0;
          const isActive = narrativeFilter === type;
          return (
            <button
              key={type}
              type="button"
              onClick={() => setNarrativeFilter(isActive ? null : type)}
              className={`rounded-2xl border p-4 text-left transition-all ${
                isActive
                  ? "border-brand-300 bg-brand-50 shadow-sm dark:border-brand-700 dark:bg-brand-950"
                  : "border-gray-200 bg-white hover:border-gray-300 dark:border-slate-800 dark:bg-slate-900 dark:hover:border-slate-700"
              }`}
            >
              <div className="text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400">
                {TYPE_LABELS[type]}
              </div>
              <div className="mt-1 text-2xl font-bold text-gray-900 dark:text-gray-50">
                {anomaliesQuery.isLoading ? "-" : count}
              </div>
            </button>
          );
        })}
      </div>

      {/* ── Anomaly feed ──────────────────────────────────────────────── */}
      <section>
        <div className="mb-4 flex items-center justify-between">
          <h2 className="text-lg font-semibold text-gray-900 dark:text-gray-50">
            Anomaly Feed
            {criticalCount > 0 && (
              <span className="ml-2 inline-flex items-center rounded-full bg-red-100 px-2.5 py-0.5 text-xs font-medium text-red-800 dark:bg-red-900/30 dark:text-red-300">
                {criticalCount} critical
              </span>
            )}
          </h2>
          {narrativeFilter && (
            <button
              type="button"
              onClick={() => setNarrativeFilter(null)}
              className="text-sm text-brand-600 hover:text-brand-700 dark:text-brand-400"
            >
              Show all
            </button>
          )}
        </div>

        {anomaliesQuery.isLoading ? (
          <AnomalyListSkeleton />
        ) : anomaliesQuery.error ? (
          <div className="rounded-xl border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-900 dark:bg-red-950/30 dark:text-red-300">
            Failed to load anomalies: {anomaliesQuery.error.message}
          </div>
        ) : filteredAnomalies.length === 0 ? (
          <div className="rounded-xl border border-green-200 bg-green-50 p-6 text-center dark:border-green-900 dark:bg-green-950/30">
            <div className="text-lg font-medium text-green-800 dark:text-green-300">
              All clear
            </div>
            <p className="mt-1 text-sm text-green-600 dark:text-green-400">
              No anomalies detected across active projects.
            </p>
          </div>
        ) : (
          <div className="space-y-2">
            {filteredAnomalies.map((anomaly, idx) => (
              <div
                key={`${anomaly.entityId}-${anomaly.type}-${idx}`}
                className="flex items-start gap-3 rounded-xl border border-gray-100 bg-white p-4 transition-colors hover:bg-gray-50 dark:border-slate-800 dark:bg-slate-900 dark:hover:bg-slate-800/80"
              >
                {/* Severity badge */}
                <span
                  className={`inline-flex shrink-0 items-center rounded-full px-2.5 py-1 text-xs font-semibold ${SEVERITY_STYLES[anomaly.severity]}`}
                >
                  {anomaly.severity === "critical" ? "Critical" : "Warning"}
                </span>

                {/* Content */}
                <div className="min-w-0 flex-1">
                  <div className="flex items-center gap-2">
                    <span className="text-xs font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500">
                      {TYPE_ICONS[anomaly.type]} {TYPE_LABELS[anomaly.type]}
                    </span>
                  </div>
                  <p className="mt-0.5 text-sm text-gray-700 dark:text-gray-300">
                    {anomaly.message}
                  </p>
                  <Link
                    href={entityLink(anomaly.type, anomaly.entityId) as Route}
                    className="mt-1 inline-block text-xs font-medium text-brand-600 hover:text-brand-700 dark:text-brand-400"
                  >
                    {anomaly.entityName} &rarr;
                  </Link>
                </div>
              </div>
            ))}
          </div>
        )}
      </section>

      {/* ── Project narrative ─────────────────────────────────────────── */}
      <section>
        <h2 className="mb-4 text-lg font-semibold text-gray-900 dark:text-gray-50">
          Project Narrative
        </h2>

        {!aiConfigQuery.data?.configured ? (
          <div className="rounded-xl border border-amber-200 bg-amber-50 p-4 dark:border-amber-900 dark:bg-amber-950/30">
            <p className="text-sm text-amber-800 dark:text-amber-300">
              AI is not configured.{" "}
              <Link
                href={"/admin/settings" as Route}
                className="font-medium underline hover:no-underline"
              >
                Configure AI credentials in Admin Settings
              </Link>{" "}
              to enable project narratives.
            </p>
          </div>
        ) : (
          <div className="rounded-2xl border border-gray-200 bg-white p-6 dark:border-slate-800 dark:bg-slate-900">
            {/* Project selector */}
            <div className="flex flex-col gap-4 sm:flex-row sm:items-end">
              <div className="flex-1">
                <label
                  htmlFor="project-select"
                  className="mb-1.5 block text-sm font-medium text-gray-700 dark:text-gray-300"
                >
                  Select project
                </label>
                <select
                  id="project-select"
                  value={selectedProjectId}
                  onChange={(e) => setSelectedProjectId(e.target.value)}
                  className="w-full rounded-xl border border-gray-300 bg-white px-3 py-2.5 text-sm text-gray-900 shadow-sm focus:border-brand-500 focus:outline-none focus:ring-1 focus:ring-brand-500 dark:border-slate-700 dark:bg-slate-800 dark:text-gray-100"
                >
                  <option value="">Choose a project...</option>
                  {projects.map((p) => (
                    <option key={p.id} value={p.id}>
                      {p.shortCode} - {p.name}
                    </option>
                  ))}
                </select>
              </div>
              <button
                type="button"
                disabled={!selectedProjectId || generateMutation.isPending}
                onClick={() => {
                  if (selectedProjectId) {
                    generateMutation.mutate({ projectId: selectedProjectId });
                  }
                }}
                className="inline-flex items-center gap-2 rounded-xl bg-brand-600 px-5 py-2.5 text-sm font-medium text-white shadow-sm transition-colors hover:bg-brand-700 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-brand-500 dark:hover:bg-brand-600"
              >
                {generateMutation.isPending ? (
                  <>
                    <svg
                      className="h-4 w-4 animate-spin"
                      viewBox="0 0 24 24"
                      fill="none"
                    >
                      <circle
                        className="opacity-25"
                        cx="12"
                        cy="12"
                        r="10"
                        stroke="currentColor"
                        strokeWidth="4"
                      />
                      <path
                        className="opacity-75"
                        fill="currentColor"
                        d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
                      />
                    </svg>
                    Generating...
                  </>
                ) : (
                  "Generate Summary"
                )}
              </button>
            </div>

            {/* Narrative display */}
            <div className="mt-6">
              {generateMutation.isPending ? (
                <NarrativeSkeleton />
              ) : generateMutation.error ? (
                <div className="rounded-xl border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-900 dark:bg-red-950/30 dark:text-red-300">
                  {generateMutation.error.message}
                </div>
              ) : generateMutation.data ? (
                <div className="rounded-xl border border-brand-200 bg-brand-50/50 p-5 dark:border-brand-900/50 dark:bg-brand-950/20">
                  <span className="inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] font-medium rounded bg-violet-100 text-violet-700 dark:bg-violet-900/30 dark:text-violet-300 mb-3">
                    <svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" />
                    </svg>
                    AI Generated
                  </span>
                  <p className="whitespace-pre-wrap text-sm leading-relaxed text-gray-800 dark:text-gray-200">
                    {generateMutation.data.narrative}
                  </p>
                  <p className="mt-3 text-xs text-gray-400 dark:text-gray-500">
                    Generated {new Date(generateMutation.data.generatedAt).toLocaleString()}
                  </p>
                </div>
              ) : cachedNarrativeQuery.data?.narrative ? (
                <div className="rounded-xl border border-gray-200 bg-gray-50/50 p-5 dark:border-slate-700 dark:bg-slate-800/50">
                  <span className="inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] font-medium rounded bg-violet-100 text-violet-700 dark:bg-violet-900/30 dark:text-violet-300 mb-3">
                    <svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" />
                    </svg>
                    AI Generated
                  </span>
                  <p className="whitespace-pre-wrap text-sm leading-relaxed text-gray-800 dark:text-gray-200">
                    {cachedNarrativeQuery.data.narrative}
                  </p>
                  <p className="mt-3 text-xs text-gray-400 dark:text-gray-500">
                    Previously generated{" "}
                    {cachedNarrativeQuery.data.generatedAt
                      ? new Date(cachedNarrativeQuery.data.generatedAt).toLocaleString()
                      : ""}
                  </p>
                </div>
              ) : selectedProjectId ? (
                <p className="text-sm text-gray-500 dark:text-gray-400">
                  Click &quot;Generate Summary&quot; to create an AI-powered executive narrative for this project.
                </p>
              ) : (
                <p className="text-sm text-gray-500 dark:text-gray-400">
                  Select a project above to generate or view its executive summary.
                </p>
              )}
            </div>
          </div>
        )}
      </section>
    </div>
  );
}
