"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { SOCIAL_PLATFORM_LIST, type SocialPlatformId } from "@/lib/social/platforms";

const REFRESH_INTERVAL_MS = 60_000;
const RELATIVE_TICK_MS = 15_000;

interface ConnectionsState {
  supabase: { url: boolean; anonKey: boolean; serviceRole: boolean };
  anthropic: { apiKey: boolean };
  openai: { apiKey: boolean };
  gemini: { apiKey: boolean };
  plaid: { clientId: boolean; secret: boolean; env: string };
  toast: { clientId: boolean; clientSecret: boolean; managementGroupGuid: boolean };
  stripe: { publishableKey: boolean; secretKey: boolean };
  google: { clientId: boolean; clientSecret: boolean; redirectUri: string };
  canva: { clientId: boolean; clientSecret: boolean; redirectUri: string };
  social: Record<SocialPlatformId, boolean>;
  site: { url: string };
}

function formatRelative(deltaMs: number): string {
  if (deltaMs < 5_000) return "just now";
  const seconds = Math.floor(deltaMs / 1000);
  if (seconds < 60) return `${seconds}s ago`;
  const minutes = Math.floor(seconds / 60);
  if (minutes < 60) return `${minutes} min ago`;
  const hours = Math.floor(minutes / 60);
  if (hours < 24) return `${hours}h ago`;
  const days = Math.floor(hours / 24);
  return `${days}d ago`;
}

export function ConnectionsStatus() {
  const [state, setState] = useState<ConnectionsState | null>(null);
  const [loading, setLoading] = useState(true);
  const [fetching, setFetching] = useState(false);
  const [lastFetchedAt, setLastFetchedAt] = useState(0);
  const [now, setNow] = useState(() => Date.now());
  const inFlightRef = useRef(false);
  const lastFetchedAtRef = useRef(0);

  const runCheck = useCallback(async (force: boolean) => {
    if (inFlightRef.current) return;
    if (!force && lastFetchedAtRef.current !== 0 && Date.now() - lastFetchedAtRef.current < REFRESH_INTERVAL_MS) {
      return;
    }
    inFlightRef.current = true;
    setFetching(true);
    try {
      const resp = await fetch("/api/system/connections");
      const data = (await resp.json()) as ConnectionsState;
      setState(data);
      const ts = Date.now();
      lastFetchedAtRef.current = ts;
      setLastFetchedAt(ts);
      setNow(ts);
    } finally {
      inFlightRef.current = false;
      setFetching(false);
      setLoading(false);
    }
  }, []);

  // First-load fetch only — skip subsequent mounts if we already have data.
  useEffect(() => {
    if (lastFetchedAtRef.current === 0) {
      void runCheck(true);
    }
  }, [runCheck]);

  // Tab focus / visibilitychange — fetch only if past the throttle window.
  useEffect(() => {
    const onVisibility = () => {
      if (document.visibilityState === "visible") {
        void runCheck(false);
      }
    };
    document.addEventListener("visibilitychange", onVisibility);
    window.addEventListener("focus", onVisibility);
    return () => {
      document.removeEventListener("visibilitychange", onVisibility);
      window.removeEventListener("focus", onVisibility);
    };
  }, [runCheck]);

  // Keep the "Last checked Xs ago" subtitle fresh.
  useEffect(() => {
    if (lastFetchedAt === 0) return;
    const id = window.setInterval(() => setNow(Date.now()), RELATIVE_TICK_MS);
    return () => window.clearInterval(id);
  }, [lastFetchedAt]);

  if (loading || !state) {
    return <Card><CardContent className="p-6 text-sm text-muted-foreground">Loading...</CardContent></Card>;
  }

  const lastCheckedLabel = lastFetchedAt === 0
    ? "Not checked yet"
    : `Last checked ${formatRelative(now - lastFetchedAt)}`;

  const supabaseLive = state.supabase.url && state.supabase.anonKey;
  const anthropicLive = state.anthropic.apiKey;
  const plaidLive = state.plaid.clientId && state.plaid.secret;
  const toastLive = state.toast.clientId && state.toast.clientSecret;
  const stripeLive = state.stripe.publishableKey && state.stripe.secretKey;
  const googleLive = state.google.clientId && state.google.clientSecret;
  const canvaLive = state.canva.clientId && state.canva.clientSecret;
  const socialLiveCount = SOCIAL_PLATFORM_LIST.filter((p) => state.social[p.id]).length;

  const summary = {
    live: [
      supabaseLive,
      anthropicLive,
      plaidLive,
      toastLive,
      stripeLive,
      googleLive,
      canvaLive,
    ].filter(Boolean).length +
      socialLiveCount,
    total: 7 + SOCIAL_PLATFORM_LIST.length,
  };

  return (
    <div className="space-y-6">
      <Card>
        <CardContent className="p-5">
          <div className="flex items-center justify-between gap-3 flex-wrap">
            <div>
              <h2 className="text-lg font-semibold">{summary.live} of {summary.total} integrations live</h2>
              <p className="text-xs text-muted-foreground">
                Local data still works without any of these — keys unlock the cloud / API-backed features.
              </p>
              <p className="text-[11px] text-muted-foreground mt-1" aria-live="polite">
                {lastCheckedLabel}
              </p>
            </div>
            <Button
              variant="outline"
              size="sm"
              onClick={() => void runCheck(true)}
              disabled={fetching}
              aria-label="Refresh connection status"
            >
              <svg
                width="14"
                height="14"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                strokeWidth="2"
                strokeLinecap="round"
                strokeLinejoin="round"
                aria-hidden="true"
                className={fetching ? "animate-spin" : undefined}
              >
                <path d="M21 12a9 9 0 1 1-3-6.7" />
                <path d="M21 4v5h-5" />
              </svg>
              {fetching ? "Refreshing..." : "Refresh now"}
            </Button>
          </div>
        </CardContent>
      </Card>

      <Group title="🤖 Anthropic Claude API" status={anthropicLive ? "live" : "pending"} description="Powers the 5 AI agents (CFO, Compliance, Secretary, Marketing, HR), document AI-summary, Marketing-Agent post drafts, reader3 doc-chat, autoresearch web research, and the council's Claude voice.">
        <Item label="ANTHROPIC_API_KEY" set={state.anthropic.apiKey} />
        <Helper
          live={anthropicLive}
          steps={[
            { label: "Open console", href: "https://console.anthropic.com/settings/keys" },
            { label: "Set spend limit", href: "https://console.anthropic.com/settings/billing" },
          ]}
        />
      </Group>

      <Group
        title="🟢 OpenAI (council voice)"
        status={state.openai.apiKey ? "live" : "pending"}
        description="Unlocks the OpenAI GPT-4o voice in the LLM Council (/app/council). Not used elsewhere today."
      >
        <Item label="OPENAI_API_KEY" set={state.openai.apiKey} optional />
        <Helper
          live={state.openai.apiKey}
          steps={[{ label: "Get an API key", href: "https://platform.openai.com/api-keys" }]}
        />
      </Group>

      <Group
        title="🔵 Google Gemini (council voice)"
        status={state.gemini.apiKey ? "live" : "pending"}
        description="Unlocks the Gemini 2.0 Flash voice in the LLM Council. Not used elsewhere today."
      >
        <Item label="GEMINI_API_KEY" set={state.gemini.apiKey} optional />
        <Helper
          live={state.gemini.apiKey}
          steps={[{ label: "Get an API key", href: "https://aistudio.google.com/apikey" }]}
        />
      </Group>

      <Group title="🏦 Plaid (bank aggregation)" status={plaidLive ? "live" : "pending"} description={`Connect Truist + other banks via Plaid Link. Mode: ${state.plaid.env}.`}>
        <Item label="PLAID_CLIENT_ID" set={state.plaid.clientId} />
        <Item label="PLAID_SECRET" set={state.plaid.secret} />
        <Item label="PLAID_ENV" set value={state.plaid.env} />
        <Helper
          live={plaidLive}
          steps={[
            { label: "Sandbox keys (free)", href: "https://dashboard.plaid.com/developers/keys" },
            { label: "Pricing for production", href: "https://plaid.com/pricing" },
          ]}
        />
      </Group>

      <Group title="🗄️ Supabase (database + auth)" status={supabaseLive ? "live" : "pending"} description="Moves all localStorage stores (bills, employees, posts, signups, license edits, TTB progress, domain renewals) to a real multi-user database. Until live, the app uses browser-local storage.">
        <Item label="NEXT_PUBLIC_SUPABASE_URL" set={state.supabase.url} />
        <Item label="NEXT_PUBLIC_SUPABASE_ANON_KEY" set={state.supabase.anonKey} />
        <Item label="SUPABASE_SERVICE_ROLE_KEY" set={state.supabase.serviceRole} optional />
        <Helper
          live={supabaseLive}
          steps={[
            { label: "Provision new project", href: "https://supabase.com/dashboard/new" },
            { label: "Run migrations/0001_init.sql + seed.sql", note: "Both files are in supabase/ — paste into Supabase SQL editor" },
            { label: "Make yourself super_admin", note: "After your first magic-link login, run the SQL in PHASE-0-HANDOFF.md §4" },
          ]}
        />
      </Group>

      <Group title="🍞 Toast POS" status={toastLive ? "live" : "pending"} description="Partner-program API integration. CSV ingest works today at /app/toast without keys.">
        <Item label="TOAST_CLIENT_ID" set={state.toast.clientId} />
        <Item label="TOAST_CLIENT_SECRET" set={state.toast.clientSecret} />
        <Item label="TOAST_MANAGEMENT_GROUP_GUID" set={state.toast.managementGroupGuid} optional />
        <Helper
          live={toastLive}
          steps={[
            { label: "Apply to Toast Partner program", href: "https://pos.toasttab.com/partner-program", note: "4-8 week approval — apply early" },
          ]}
        />
      </Group>

      <Group title="💳 Stripe" status={stripeLive ? "live" : "pending"} description="Phase 8 — Reg CF crowdfund disbursement and subscription billing. Not required until raises go live.">
        <Item label="STRIPE_PUBLISHABLE_KEY" set={state.stripe.publishableKey} optional />
        <Item label="STRIPE_SECRET_KEY" set={state.stripe.secretKey} optional />
        <Helper
          live={stripeLive}
          steps={[{ label: "Get API keys", href: "https://dashboard.stripe.com/apikeys" }]}
        />
      </Group>

      <Group title="📬 Google / Gmail" status={googleLive ? "live" : "pending"} description="Connect 8+ Gmail accounts for unified inbox + Secretary Agent triage. Each account stays read-only by default.">
        <Item label="GOOGLE_CLIENT_ID" set={state.google.clientId} />
        <Item label="GOOGLE_CLIENT_SECRET" set={state.google.clientSecret} />
        <Item label="GOOGLE_REDIRECT_URI" set value={state.google.redirectUri} />
        <Helper
          live={googleLive}
          steps={[
            { label: "Create Google Cloud project", href: "https://console.cloud.google.com/projectcreate" },
            { label: "Enable Gmail API", href: "https://console.cloud.google.com/apis/library/gmail.googleapis.com" },
            { label: "Create OAuth 2.0 Client ID (Web app)", href: "https://console.cloud.google.com/apis/credentials" },
            { label: "Add http://localhost:3000/api/google/callback as authorized redirect URI" },
            { label: "Step-by-step in GMAIL_SETUP.md (repo root)" },
          ]}
        />
      </Group>

      <Group
        title="📐 Canva Connect"
        status={canvaLive ? "live" : "pending"}
        description="Pull designs into the social composer and round-trip exports (PNG/JPG/PDF) back into SAG Manager. Required for the “Design with Canva” button in the composer."
      >
        <Item label="CANVA_CLIENT_ID" set={state.canva.clientId} />
        <Item label="CANVA_CLIENT_SECRET" set={state.canva.clientSecret} />
        <Item label="CANVA_REDIRECT_URI" set value={state.canva.redirectUri} />
        <Helper
          live={canvaLive}
          steps={[
            { label: "Open Canva developer portal", href: "https://www.canva.com/developers/" },
            { label: "Create an Integration (Connect API)" },
            { label: "Add http://localhost:3000/api/canva/callback as redirect URI" },
            { label: "Required scopes: design:content:read, design:meta:read, design:content:write, asset:read" },
            { label: "Walkthrough in CANVA_SETUP.md (repo root)" },
          ]}
        />
      </Group>

      <Group
        title="📣 Social media platforms"
        status={socialLiveCount > 0 ? "live" : "pending"}
        description={`${socialLiveCount} of ${SOCIAL_PLATFORM_LIST.length} platforms have OAuth keys configured. Meta covers Instagram + Facebook with a single app. Full setup steps in SOCIAL_SETUP.md.`}
      >
        {SOCIAL_PLATFORM_LIST.map((plat) => {
          const configured = state.social[plat.id];
          return (
            <div
              key={plat.id}
              className="flex items-center justify-between rounded-md border bg-background p-2.5 text-sm"
            >
              <div className="flex items-center gap-2">
                <span
                  className="w-7 h-7 rounded-full flex items-center justify-center text-base"
                  style={{ backgroundColor: `${plat.color}25` }}
                >
                  {plat.icon}
                </span>
                <div className="min-w-0">
                  <div className="text-sm font-medium">{plat.label}</div>
                  <code className="text-[10px] text-muted-foreground">
                    {plat.envVars.join(" + ")}
                  </code>
                </div>
              </div>
              <div className="flex items-center gap-2 shrink-0">
                {configured ? (
                  <Badge variant="success" className="text-[10px]">
                    KEYS SET
                  </Badge>
                ) : (
                  <Badge variant="outline" className="text-[10px]">
                    PENDING
                  </Badge>
                )}
                <a
                  href={plat.developerPortalUrl}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="text-[10px] text-[var(--sag-brand)] hover:underline"
                >
                  Portal ↗
                </a>
              </div>
            </div>
          );
        })}
        <p className="text-[11px] text-muted-foreground pt-1">
          SAG Manager scaffolds Meta OAuth today (covers IG + FB). Stubs for the rest return 503
          with setup pointers; flip them live by adding the listed env vars + writing the
          equivalent /api/&lt;platform&gt;/callback route.
        </p>
      </Group>

      <Card className="border-dashed">
        <CardContent className="p-5">
          <h3 className="text-base font-semibold">How to edit</h3>
          <p className="mt-2 text-sm text-muted-foreground">
            All keys live in <code className="text-xs bg-muted px-1 py-0.5 rounded">C:\dev\south-armz-global\.env.local</code> — gitignored, never committed.
            After editing, restart <code className="text-xs bg-muted px-1 py-0.5 rounded">npm run dev</code> so Next.js picks up the new values.
          </p>
        </CardContent>
      </Card>
    </div>
  );
}

function Group({
  title,
  status,
  description,
  children,
}: {
  title: string;
  status: "live" | "pending";
  description: string;
  children: React.ReactNode;
}) {
  return (
    <Card>
      <CardContent className="p-5">
        <div className="flex items-center justify-between mb-2 flex-wrap gap-2">
          <h3 className="text-base font-semibold">{title}</h3>
          <Badge variant={status === "live" ? "success" : "warning"}>
            {status === "live" ? "Live" : "Pending"}
          </Badge>
        </div>
        <p className="text-sm text-muted-foreground">{description}</p>
        <div className="mt-4 space-y-2">{children}</div>
      </CardContent>
    </Card>
  );
}

function Item({ label, set, value, optional }: { label: string; set: boolean; value?: string; optional?: boolean }) {
  return (
    <div className="flex items-center justify-between rounded-md border bg-background p-2.5 text-sm">
      <code className="text-xs font-mono">{label}</code>
      <div className="flex items-center gap-2">
        {value && <span className="text-xs text-muted-foreground">{value}</span>}
        {set ? (
          <Badge variant="success" className="text-[10px]">SET</Badge>
        ) : optional ? (
          <Badge variant="outline" className="text-[10px]">OPTIONAL</Badge>
        ) : (
          <Badge variant="warning" className="text-[10px]">MISSING</Badge>
        )}
      </div>
    </div>
  );
}

function Helper({ live, steps }: { live: boolean; steps: Array<{ label: string; href?: string; note?: string }> }) {
  if (live) {
    return <p className="text-xs text-green-700 dark:text-green-400">✓ All required keys configured.</p>;
  }
  return (
    <div className="rounded-md border border-dashed p-3 bg-muted/30">
      <div className="text-xs font-medium mb-2">To finish setup:</div>
      <ul className="space-y-1.5 text-xs">
        {steps.map((s, i) => (
          <li key={i} className="flex items-start gap-2">
            <span className="text-muted-foreground">{i + 1}.</span>
            <div>
              {s.href ? (
                <a href={s.href} target="_blank" rel="noopener noreferrer" className="text-[var(--sag-brand)] hover:underline font-medium">
                  {s.label} ↗
                </a>
              ) : (
                <span className="font-medium">{s.label}</span>
              )}
              {s.note && <div className="text-muted-foreground">{s.note}</div>}
            </div>
          </li>
        ))}
      </ul>
    </div>
  );
}
