/**
 * ConsentDashboard — per-video consent toggle page for creators.
 *
 * Shows all videos with three consent toggles each (KB inclusion,
 * Training usage, Public display). Each card has an expandable
 * audit history section loaded on first expand.
 */

import { useEffect, useState, useCallback } from "react";
import { SidebarNav } from "./CreatorDashboard";
import dashStyles from "./CreatorDashboard.module.css";
import styles from "./ConsentDashboard.module.css";
import { useAuth } from "../context/AuthContext";
import { useDocumentTitle } from "../hooks/useDocumentTitle";
import { ToggleSwitch } from "../components/ToggleSwitch";
import {
  fetchConsentList,
  updateVideoConsent,
  fetchConsentHistory,
  type VideoConsentRead,
  type ConsentAuditEntry,
} from "../api/consent";
import { ApiError } from "../api/client";

// ── Types ────────────────────────────────────────────────────────────────────

type ConsentField = "kb_inclusion" | "training_usage" | "public_display";

interface VideoCardState {
  consent: VideoConsentRead;
  historyOpen: boolean;
  historyLoaded: boolean;
  historyLoading: boolean;
  history: ConsentAuditEntry[];
  updating: ConsentField | null;
  updateError: string | null;
}

// ── Field labels ─────────────────────────────────────────────────────────────

const CONSENT_FIELDS: { key: ConsentField; label: string }[] = [
  { key: "kb_inclusion", label: "Knowledge Base Inclusion" },
  { key: "training_usage", label: "AI Training Usage" },
  { key: "public_display", label: "Public Display" },
];

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

export default function ConsentDashboard() {
  useDocumentTitle("Consent Settings");
  const { user: _user } = useAuth();

  const [cards, setCards] = useState<VideoCardState[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // ── Fetch consent list on mount ──────────────────────────────────────────

  useEffect(() => {
    let cancelled = false;
    setLoading(true);
    setError(null);

    fetchConsentList()
      .then((res) => {
        if (cancelled) return;
        setCards(
          res.items.map((consent) => ({
            consent,
            historyOpen: false,
            historyLoaded: false,
            historyLoading: false,
            history: [],
            updating: null,
            updateError: null,
          })),
        );
      })
      .catch((err) => {
        if (cancelled) return;
        setError(
          err instanceof ApiError
            ? err.detail
            : "Failed to load consent settings",
        );
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });

    return () => {
      cancelled = true;
    };
  }, []);

  // ── Toggle handler ────────────────────────────────────────────────────────

  const handleToggle = useCallback(
    async (videoId: string, field: ConsentField, newValue: boolean) => {
      // Optimistic update
      setCards((prev) =>
        prev.map((c) =>
          c.consent.source_video_id === videoId
            ? {
                ...c,
                consent: { ...c.consent, [field]: newValue },
                updating: field,
                updateError: null,
              }
            : c,
        ),
      );

      try {
        const updated = await updateVideoConsent(videoId, {
          [field]: newValue,
        });
        setCards((prev) =>
          prev.map((c) =>
            c.consent.source_video_id === videoId
              ? { ...c, consent: updated, updating: null }
              : c,
          ),
        );
      } catch (err) {
        // Revert optimistic update
        setCards((prev) =>
          prev.map((c) =>
            c.consent.source_video_id === videoId
              ? {
                  ...c,
                  consent: { ...c.consent, [field]: !newValue },
                  updating: null,
                  updateError:
                    err instanceof ApiError
                      ? err.detail
                      : "Update failed — try again",
                }
              : c,
          ),
        );
      }
    },
    [],
  );

  // ── History expand handler ────────────────────────────────────────────────

  const toggleHistory = useCallback(async (videoId: string) => {
    setCards((prev) =>
      prev.map((c) => {
        if (c.consent.source_video_id !== videoId) return c;
        if (c.historyOpen) return { ...c, historyOpen: false };
        // Opening — need to load if not yet loaded
        if (c.historyLoaded) return { ...c, historyOpen: true };
        return { ...c, historyOpen: true, historyLoading: true };
      }),
    );

    // Check if we need to fetch
    const card = cards.find((c) => c.consent.source_video_id === videoId);
    if (!card || card.historyLoaded) return;

    try {
      const history = await fetchConsentHistory(videoId);
      setCards((prev) =>
        prev.map((c) =>
          c.consent.source_video_id === videoId
            ? { ...c, history, historyLoaded: true, historyLoading: false }
            : c,
        ),
      );
    } catch {
      setCards((prev) =>
        prev.map((c) =>
          c.consent.source_video_id === videoId
            ? {
                ...c,
                historyLoading: false,
                history: [],
                historyLoaded: true,
              }
            : c,
        ),
      );
    }
  }, [cards]);

  // ── Render ────────────────────────────────────────────────────────────────

  return (
    <div className={dashStyles.layout}>
      <SidebarNav />
      <div className={dashStyles.content}>
        <h1 className={styles.heading}>Consent Settings</h1>

        {loading && (
          <div className={styles.loading}>Loading consent data…</div>
        )}

        {!loading && error && <div className={styles.error}>{error}</div>}

        {!loading && !error && cards.length === 0 && (
          <div className={styles.emptyState}>
            <h2>No Videos</h2>
            <p>
              No videos found for your creator profile. Upload content to manage
              consent settings.
            </p>
          </div>
        )}

        {!loading &&
          !error &&
          cards.map((card) => (
            <VideoConsentCard
              key={card.consent.source_video_id}
              card={card}
              onToggle={handleToggle}
              onToggleHistory={toggleHistory}
            />
          ))}
      </div>
    </div>
  );
}

// ── Video card ───────────────────────────────────────────────────────────────

function VideoConsentCard({
  card,
  onToggle,
  onToggleHistory,
}: {
  card: VideoCardState;
  onToggle: (
    videoId: string,
    field: ConsentField,
    newValue: boolean,
  ) => void;
  onToggleHistory: (videoId: string) => void;
}) {
  const { consent, historyOpen, historyLoading, history, updating, updateError } =
    card;
  const videoId = consent.source_video_id;

  return (
    <div className={styles.videoRow}>
      <h3 className={styles.videoTitle}>{consent.video_filename}</h3>

      <div className={styles.toggleGroup}>
        {CONSENT_FIELDS.map(({ key, label }) => (
          <div className={styles.toggleRow} key={key}>
            <ToggleSwitch
              checked={consent[key]}
              onChange={(val) => onToggle(videoId, key, val)}
              label={label}
              disabled={updating === key}
            />
          </div>
        ))}
      </div>

      {updateError && <p className={styles.updateError}>{updateError}</p>}

      <button
        className={styles.historyToggle}
        onClick={() => onToggleHistory(videoId)}
        aria-expanded={historyOpen}
      >
        <span
          className={`${styles.historyArrow} ${historyOpen ? styles.historyArrowOpen : ""}`}
        >
          ▸
        </span>
        {historyOpen ? "Hide history" : "Show history"}
      </button>

      {historyOpen && (
        <>
          {historyLoading && (
            <p className={styles.loading} style={{ padding: "0.5rem 0" }}>
              Loading history…
            </p>
          )}
          {!historyLoading && history.length === 0 && (
            <p
              style={{
                fontSize: "0.8125rem",
                color: "var(--color-text-secondary)",
                marginTop: "0.5rem",
              }}
            >
              No changes recorded yet.
            </p>
          )}
          {!historyLoading && history.length > 0 && (
            <ul className={styles.historyList}>
              {history.map((entry, i) => (
                <li key={i} className={styles.historyEntry}>
                  <span className={styles.historyField}>
                    {entry.field_name}
                  </span>
                  <span>
                    {entry.old_value === null
                      ? "set to"
                      : entry.old_value
                        ? "on → off"
                        : "off → on"}
                  </span>
                  <span>by {entry.changed_by}</span>
                  <span className={styles.historyDate}>
                    {new Date(entry.created_at).toLocaleDateString(undefined, {
                      year: "numeric",
                      month: "short",
                      day: "numeric",
                      hour: "2-digit",
                      minute: "2-digit",
                    })}
                  </span>
                </li>
              ))}
            </ul>
          )}
        </>
      )}
    </div>
  );
}
