import { createFileRoute, useRouter } from "@tanstack/react-router";
import { useState } from "react";
import { toast } from "sonner";
import { AppShell, PageHeader } from "@/components/app-shell";
import { StatusPill } from "@/components/hub-dashboard";
import { SocialConnections, SocialListening } from "@/components/social-desk";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent } from "@/components/ui/card";
import { Switch } from "@/components/ui/switch";
import { getShellMeta } from "@/lib/server/api-core";
import { getMediaLibrary, getSocialAnalytics, getSocialQueue, setMediaPermission } from "@/lib/server/api-hub";
import { getSocialDesk } from "@/lib/server/api-social";
import { formatDateTime } from "@/lib/utils";

export const Route = createFileRoute("/content/scheduler")({
  validateSearch: (search: Record<string, unknown>) => ({
    oauth: typeof search.oauth === "string" ? search.oauth : undefined,
    network: typeof search.network === "string" ? search.network : undefined,
  }),
  loader: async () => {
    const [meta, queue, media, analytics, desk] = await Promise.all([
      getShellMeta(),
      getSocialQueue(),
      getMediaLibrary(),
      getSocialAnalytics(),
      getSocialDesk(),
    ]);
    return { meta, queue, media, analytics, desk };
  },
  component: SchedulerPage,
});

const FLAGS = [
  { field: "can_public" as const, label: "Public site" },
  { field: "can_social" as const, label: "Social queue" },
  { field: "can_donor" as const, label: "Donor desk" },
  { field: "can_student" as const, label: "Student desk" },
];

function SchedulerPage() {
  const { meta, queue, media, analytics, desk } = Route.useLoaderData();
  const { oauth, network } = Route.useSearch();
  const router = useRouter();
  const [busy, setBusy] = useState<string | null>(null);

  async function toggle(id: string, field: (typeof FLAGS)[number]["field"], value: boolean) {
    setBusy(`${id}:${field}`);
    try {
      const res = await setMediaPermission({ data: { id, field, value } });
      if (!res.ok) {
        toast.error(res.error);
        return;
      }
      toast.success("Permission saved");
      await router.invalidate();
    } finally {
      setBusy(null);
    }
  }

  return (
    <AppShell hold={meta.hold} unread={meta.unread} noticeCount={meta.noticeCount} inboxUnread={meta.inboxUnread}>
      <PageHeader
        kicker="Content"
        title="Social scheduler"
        description="OAuth2 accounts, listening, queue, media rights, and last-seven-day analytics. Scheduled does not mean sent — a staff member still publishes."
      />

      {oauth === "demo" ? (
        <p className="mb-4 rounded-lg border border-warning/40 bg-warning/10 px-3 py-2 text-sm">
          {network ?? "That network"} has no live OAuth2 keys yet. Use Connect on the card to attach a preview handle.
        </p>
      ) : null}
      {oauth === "ok" ? (
        <p className="mb-4 rounded-lg border border-success/40 bg-success/10 px-3 py-2 text-sm">
          {network ?? "Account"} connected.
        </p>
      ) : null}

      <h2 className="mb-3 font-display text-2xl">Accounts · OAuth2</h2>
      <SocialConnections connections={desk.connections} />

      <h2 className="mb-3 font-display text-2xl">Listening</h2>
      <SocialListening keywords={desk.keywords} mentions={desk.mentions} />

      <h2 className="mb-3 font-display text-2xl">Analytics · last 7 days</h2>
      <div className="mb-8 grid gap-3 sm:grid-cols-3">
        {analytics.rows.map((row) => (
          <Card key={row.id}>
            <CardContent className="p-4">
              <p className="text-[11px] font-medium tracking-[0.16em] text-primary uppercase">{row.platform}</p>
              <p className="mt-2 font-display text-3xl tabular">{row.impressions.toLocaleString()}</p>
              <p className="text-xs text-muted-foreground">impressions</p>
              <dl className="mt-3 grid grid-cols-3 gap-2 text-xs">
                <div>
                  <dt className="text-muted-foreground">Engage</dt>
                  <dd className="font-medium tabular">{row.engagements.toLocaleString()}</dd>
                </div>
                <div>
                  <dt className="text-muted-foreground">Clicks</dt>
                  <dd className="font-medium tabular">{row.clicks.toLocaleString()}</dd>
                </div>
                <div>
                  <dt className="text-muted-foreground">Follows</dt>
                  <dd className="font-medium tabular">{row.follows.toLocaleString()}</dd>
                </div>
              </dl>
            </CardContent>
          </Card>
        ))}
      </div>

      <h2 className="mb-3 font-display text-2xl">Queue</h2>
      <Card className="mb-8">
        <CardContent className="overflow-x-auto pt-5">
          <table className="w-full min-w-[44rem] text-left text-sm">
            <thead className="text-[11px] tracking-wide text-muted-foreground uppercase">
              <tr className="border-b border-border">
                <th className="pb-2 font-medium">When</th>
                <th className="pb-2 font-medium">Platform</th>
                <th className="pb-2 font-medium">Campaign</th>
                <th className="pb-2 font-medium">Copy</th>
                <th className="pb-2 font-medium">Status</th>
              </tr>
            </thead>
            <tbody>
              {queue.rows.map((row) => (
                <tr key={row.id} className="border-b border-border/70 align-top">
                  <td className="py-3 text-xs text-muted-foreground">{formatDateTime(row.scheduled_at)}</td>
                  <td className="py-3 font-medium">{row.platform}</td>
                  <td className="py-3 text-muted-foreground">{row.campaign ?? "—"}</td>
                  <td className="py-3 max-w-md">{row.body}</td>
                  <td className="py-3">
                    <StatusPill status={row.status} />
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </CardContent>
      </Card>

      <h2 className="mb-3 font-display text-2xl">Media & permissions</h2>
      <p className="mb-4 max-w-2xl text-sm text-muted-foreground">
        Lockup, crest, and studio stills. Flip where each asset may appear. Captions stay educational — no clinical or
        concussion-rate claim.
      </p>
      <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-3">
        {media.rows.map((row) => (
          <Card key={row.id}>
            <CardContent className="pt-5">
              {row.kind === "image" ? (
                <img src={row.src} alt={row.title} className="mb-3 h-40 w-full rounded-lg bg-muted object-contain" />
              ) : (
                <div className="mb-3 flex h-40 items-center justify-center rounded-lg bg-muted text-sm text-muted-foreground">
                  {row.kind}
                </div>
              )}
              <div className="flex flex-wrap items-center gap-2">
                <Badge variant="outline">{row.kind}</Badge>
                <span className="text-xs text-muted-foreground">{formatDateTime(row.posted_at)}</span>
              </div>
              <p className="mt-2 font-medium">{row.title}</p>
              {row.caption ? <p className="mt-1 text-sm text-muted-foreground">{row.caption}</p> : null}
              <ul className="mt-4 space-y-2 border-t border-border pt-3">
                {FLAGS.map((flag) => (
                  <li key={flag.field} className="flex items-center justify-between gap-3 text-sm">
                    <span>{flag.label}</span>
                    <Switch
                      checked={row[flag.field]}
                      disabled={busy === `${row.id}:${flag.field}`}
                      onCheckedChange={(value) => void toggle(row.id, flag.field, value)}
                    />
                  </li>
                ))}
              </ul>
            </CardContent>
          </Card>
        ))}
      </div>
    </AppShell>
  );
}
