"use client";

import { useEffect, useState, useCallback } from "react";
import { useParams } from "next/navigation";
import Link from "next/link";
import { api } from "@/lib/api";
import { getSocket, joinNegotiation, leaveNegotiation } from "@/lib/socket";
import type { Negotiation, Round, SatisfactionPoint, ConcessionEntry } from "@/lib/types";
import {
  FEATURE_LABELS,
  STATUS_COLORS,
  STATUS_LABELS,
  PERSONALITY_LABELS,
  relativeTime,
} from "@/lib/utils";
import type { Personality } from "@/lib/types";
import SatisfactionChart from "@/components/SatisfactionChart";
import FairnessScore from "@/components/FairnessScore";
import ConcessionTimeline from "@/components/ConcessionTimeline";
import NegotiationTimeline from "@/components/NegotiationTimeline";
import ResolutionCard from "@/components/ResolutionCard";

function Icon({ name, className = "" }: { name: string; className?: string }) {
  return <span className={`material-symbols-outlined ${className}`}>{name}</span>;
}

const FEATURE_ICONS: Record<string, string> = {
  scheduling: "calendar_month",
  expenses: "account_balance_wallet",
  freelance: "work",
  roommate: "home",
  trip: "flight_takeoff",
  marketplace: "store",
  collaborative: "groups",
  conflict: "gavel",
  generic: "hub",
};

export default function NegotiationDetailPage() {
  const params = useParams<{ id: string }>();
  const id = params.id;

  const [negotiation, setNegotiation] = useState<Negotiation | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [connected, setConnected] = useState(false);
  const [liveRound, setLiveRound] = useState<number | null>(null);

  const load = useCallback(async () => {
    try {
      const data = await api.negotiation(id);
      setNegotiation(data);
      setError(null);
    } catch (e) {
      setError(String(e));
    } finally {
      setLoading(false);
    }
  }, [id]);

  useEffect(() => {
    load();
    const socket = getSocket();
    const onConnect = () => setConnected(true);
    const onDisconnect = () => setConnected(false);
    const onState = (data: Negotiation) => { setNegotiation(data); setLoading(false); };
    const onRound = (payload: { negotiation_id: string; round: Round }) => {
      if (payload.negotiation_id !== id) return;
      setLiveRound(payload.round.round_number);
      setNegotiation((prev) => {
        if (!prev) return prev;
        const rounds = [...(prev.rounds ?? [])];
        const idx = rounds.findIndex((r) => r.id === payload.round.id);
        if (idx >= 0) rounds[idx] = payload.round; else rounds.push(payload.round);
        return { ...prev, rounds, status: "active" };
      });
    };
    const onResolved = (payload: { negotiation_id: string }) => {
      if (payload.negotiation_id !== id) return;
      setLiveRound(null);
      load();
    };
    socket.on("connect", onConnect);
    socket.on("disconnect", onDisconnect);
    socket.on("negotiation_state", onState);
    socket.on("round_update", onRound);
    socket.on("negotiation_resolved", onResolved);
    setConnected(socket.connected);
    joinNegotiation(id);
    return () => {
      leaveNegotiation(id);
      socket.off("connect", onConnect);
      socket.off("disconnect", onDisconnect);
      socket.off("negotiation_state", onState);
      socket.off("round_update", onRound);
      socket.off("negotiation_resolved", onResolved);
    };
  }, [id, load]);

  if (loading) return <Shell><LoadingState /></Shell>;
  if (error) return <Shell><ErrorState message={error} onRetry={load} /></Shell>;
  if (!negotiation) return <Shell><ErrorState message="Negotiation not found" onRetry={load} /></Shell>;

  const rounds = negotiation.rounds ?? [];
  const participants = negotiation.participants ?? [];
  const analytics = negotiation.analytics;
  const isLive = negotiation.status === "active";

  const satTimeline: SatisfactionPoint[] =
    analytics?.satisfaction_timeline?.length
      ? analytics.satisfaction_timeline
      : rounds.map((r) => ({ round: r.round_number, score_a: r.satisfaction_a, score_b: r.satisfaction_b }));

  const concessions: ConcessionEntry[] = analytics?.concession_log ?? [];
  const lastSat = satTimeline[satTimeline.length - 1];
  const fairness = analytics?.fairness_score ?? (lastSat ? 100 - Math.abs(lastSat.score_a - lastSat.score_b) : null);

  const userA = participants[0];
  const userB = participants[1];

  return (
    <Shell>
      {/* ── Header ── */}
      <div className="flex items-start justify-between gap-4 mb-6">
        <div className="flex items-center gap-3">
          <Link
            href="/"
            className="p-2 rounded-lg bg-white/5 border border-white/10 text-slate-400 hover:text-white hover:border-white/20 transition-all"
          >
            <Icon name="arrow_back" className="text-lg" />
          </Link>
          <div className="size-10 rounded-lg bg-white/5 border border-white/10 flex items-center justify-center">
            <Icon name={FEATURE_ICONS[negotiation.feature_type] ?? "hub"} className="text-[#B7A6FB]" />
          </div>
          <div>
            <div className="flex items-center gap-2 flex-wrap">
              <h1 className="text-base font-bold text-white font-mono">{id}</h1>
              <span className={`text-[10px] px-2 py-0.5 rounded-full border font-medium ${STATUS_COLORS[negotiation.status]}`}>
                {STATUS_LABELS[negotiation.status]}
              </span>
              <span className="text-[10px] px-2 py-0.5 bg-white/5 text-slate-400 rounded-full border border-white/10">
                {FEATURE_LABELS[negotiation.feature_type]}
              </span>
            </div>
            <p className="text-[10px] text-slate-600 mt-0.5 font-mono">
              Started {relativeTime(negotiation.created_at)}
              {liveRound && (
                <span className="ml-2 text-[#B7A6FB] animate-pulse">
                  · Round {liveRound} processing…
                </span>
              )}
            </p>
          </div>
        </div>

        <div className="flex items-center gap-2 shrink-0">
          <div className={`flex items-center gap-1.5 text-[10px] px-2.5 py-1 rounded-full border font-mono ${connected ? "bg-emerald-500/10 text-emerald-400 border-emerald-500/20" : "bg-white/5 text-slate-500 border-white/10"}`}>
            <span className={`size-1.5 rounded-full ${connected ? "bg-emerald-400 animate-pulse" : "bg-slate-600"}`} />
            {connected ? "Live" : "Offline"}
          </div>
          {isLive && (
            <span className="flex items-center gap-1.5 text-[10px] px-2.5 py-1 rounded-full border bg-red-500/10 text-red-400 border-red-500/20 font-mono animate-pulse">
              <span className="size-1.5 rounded-full bg-red-500" />
              Negotiating · Rd {liveRound ?? rounds.length}
            </span>
          )}
          <button onClick={load} className="p-2 rounded-lg bg-white/5 border border-white/10 text-slate-400 hover:text-white hover:border-white/20 transition-all" title="Refresh">
            <Icon name="refresh" className="text-lg" />
          </button>
        </div>
      </div>

      {/* ── Participants ── */}
      {participants.length > 0 && (
        <div className="grid grid-cols-2 gap-3 mb-6">
          {[userA, userB].filter(Boolean).map((p, i) => (
            <ParticipantCard key={i} participant={p} label={i === 0 ? "A" : "B"} />
          ))}
        </div>
      )}

      {/* ── Main 2-col grid ── */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-5">
        {/* Left */}
        <div className="space-y-5">
          <Section title="Convergence Timeline" icon="show_chart">
            <SatisfactionChart data={satTimeline} />
          </Section>

          {fairness !== null && (
            <Section title="Fairness Score" icon="balance">
              <FairnessScore score={fairness} satA={lastSat?.score_a} satB={lastSat?.score_b} />
            </Section>
          )}

          {(negotiation.status === "resolved" || negotiation.status === "escalated") && (
            <Section title="Resolution" icon="check_circle">
              <ResolutionCard negotiation={negotiation} />
              <Link
                href={`/negotiation/${id}/resolved`}
                className="mt-4 flex items-center justify-between gap-3 w-full px-4 py-3.5 rounded-xl border border-[#B7A6FB]/25 bg-[#B7A6FB]/6 hover:bg-[#B7A6FB]/12 hover:border-[#B7A6FB]/50 transition-all group"
                style={{ boxShadow: "0 0 18px rgba(183,166,251,0.08)" }}
              >
                <div className="flex items-center gap-3">
                  <div className="size-9 rounded-lg bg-[#B7A6FB]/15 flex items-center justify-center text-[#B7A6FB] shrink-0">
                    <Icon name="verified" className="text-lg" />
                  </div>
                  <div>
                    <p className="text-sm font-bold text-white leading-none mb-0.5">View Settlement Details</p>
                    <p className="text-[10px] text-slate-500 font-mono">Blockchain record · UPI · Full transcript</p>
                  </div>
                </div>
                <Icon name="arrow_forward" className="text-[#B7A6FB] text-lg group-hover:translate-x-0.5 transition-transform" />
              </Link>
            </Section>
          )}
        </div>

        {/* Right */}
        <div className="space-y-5">
          <Section
            title={`Negotiation Stream (${rounds.length} round${rounds.length !== 1 ? "s" : ""})`}
            icon="receipt_long"
          >
            <NegotiationTimeline rounds={rounds} participants={participants} />
          </Section>

          {concessions.length > 0 && (
            <Section title="Concession Log" icon="swap_horiz">
              <ConcessionTimeline concessions={concessions} />
            </Section>
          )}
        </div>
      </div>
    </Shell>
  );
}

// ─── Sub-components ───────────────────────────────────────────────────────────

function Shell({ children }: { children: React.ReactNode }) {
  return (
    <div className="min-h-screen bg-[#020105] text-white relative">
      <div className="absolute inset-0 bg-grid-subtle opacity-20 pointer-events-none" />

      {/* Top bar */}
      <header className="h-16 flex items-center justify-between px-6 bg-[#050505]/80 backdrop-blur-md border-b border-white/5 sticky top-0 z-30">
        <div className="flex items-center gap-3">
          <div className="flex items-center justify-center size-8 rounded-lg bg-[#B7A6FB]/10 border border-[#B7A6FB]/20 text-[#B7A6FB]">
            <Icon name="hub" className="text-lg" />
          </div>
          <h1 className="text-sm font-bold tracking-tight text-white">
            Agent<span className="text-[#B7A6FB] font-light">Mesh</span>
          </h1>
        </div>
        <nav className="hidden md:flex items-center gap-1">
          <Link href="/" className="text-slate-400 hover:text-white hover:bg-white/5 px-3 py-1.5 rounded-md transition-all text-xs font-medium">
            Dashboard
          </Link>
          <span className="text-white bg-[#B7A6FB]/10 border border-[#B7A6FB]/20 px-3 py-1.5 rounded-md text-xs font-medium">
            Active Agents
          </span>
          <a href="#" className="text-slate-400 hover:text-white hover:bg-white/5 px-3 py-1.5 rounded-md transition-all text-xs font-medium">History</a>
          <a href="#" className="text-slate-400 hover:text-white hover:bg-white/5 px-3 py-1.5 rounded-md transition-all text-xs font-medium">Settings</a>
        </nav>
        <button className="flex items-center gap-1.5 px-3 py-1.5 bg-[#B7A6FB] text-black rounded-md text-xs font-bold hover:bg-white transition-all shadow-[0_0_10px_rgba(183,166,251,0.2)]">
          <Icon name="add" className="text-sm" /> New Session
        </button>
      </header>

      <div className="max-w-6xl mx-auto px-4 py-6 relative z-10">{children}</div>
    </div>
  );
}

function Section({ title, icon, children }: { title: string; icon: string; children: React.ReactNode }) {
  return (
    <div className="glass-card rounded-xl p-5">
      <div className="flex items-center gap-2 mb-4">
        <Icon name={icon} className="text-[#B7A6FB] text-lg" />
        <h2 className="text-xs font-bold text-white uppercase tracking-wider">{title}</h2>
      </div>
      {children}
    </div>
  );
}

function ParticipantCard({
  participant,
  label,
}: {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  participant: any;
  label: string;
}) {
  if (!participant) return null;
  const pers = (participant.personality_used ?? "balanced") as Personality;
  const name = participant.display_name || participant.username || `Agent ${label}`;
  const isA = label === "A";

  return (
    <div className={`glow-border rounded-xl p-4 flex items-center gap-3 ${isA ? "bg-[#B7A6FB]/5" : "bg-cyan-900/5"}`}>
      <div className={`size-10 rounded-full flex items-center justify-center text-sm font-bold shrink-0 ${isA ? "bg-[#B7A6FB]/15 text-[#B7A6FB]" : "bg-cyan-900/20 text-cyan-400"}`}>
        {label}
      </div>
      <div className="min-w-0">
        <p className="text-sm font-medium text-white truncate">{name}</p>
        <span className={`text-[9px] font-mono px-1.5 py-0.5 rounded border ${isA ? "text-[#B7A6FB] bg-[#B7A6FB]/10 border-[#B7A6FB]/20" : "text-cyan-400 bg-cyan-500/10 border-cyan-500/20"}`}>
          {PERSONALITY_LABELS[pers]}
        </span>
      </div>
    </div>
  );
}

function LoadingState() {
  return (
    <div className="flex flex-col items-center justify-center py-32 gap-3 text-slate-600">
      <Icon name="refresh" className="text-4xl animate-spin text-[#B7A6FB]" />
      <span className="text-xs font-mono uppercase tracking-wider">Loading negotiation…</span>
    </div>
  );
}

function ErrorState({ message, onRetry }: { message: string; onRetry: () => void }) {
  return (
    <div className="py-24 text-center space-y-4">
      <Icon name="error" className="text-5xl text-red-400 block mx-auto" />
      <p className="text-red-400 text-sm">{message}</p>
      <button onClick={onRetry} className="text-[10px] text-slate-400 hover:text-white underline font-mono">
        Retry
      </button>
    </div>
  );
}
