"use client";

import { useState, useEffect, useCallback } from "react";
import {
  DollarSign,
  Zap,
  Shield,
  ExternalLink,
  Check,
  X,
  Cpu,
  TrendingUp,
  AlertTriangle,
  Loader2,
  PartyPopper,
  Clock,
} from "lucide-react";

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

interface OperatorSettings {
  marketplaceEnabled: boolean;
  pricePerMToken: number;
  autoPrice: boolean;
  availableModels: string[];
}

interface EarningsSummary {
  totalRevenue: number;
  operatorShare: number;
  totalRequests: number;
  periodDays: number;
  dailyAverage: number;
  firstBookingAt: string | null;
  lifetimeRequests: number;
}

interface StripeConnectStatus {
  connected: boolean;
  accountId?: string;
}

interface TermsStatus {
  accepted: boolean;
  acceptedAt: string | null;
}

// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------

export function OperatorDashboard({ userId }: { userId: string }) {
  const [settings, setSettings] = useState<OperatorSettings | null>(null);
  const [earnings, setEarnings] = useState<EarningsSummary | null>(null);
  const [stripeStatus, setStripeStatus] = useState<StripeConnectStatus | null>(
    null,
  );
  const [termsStatus, setTermsStatus] = useState<TermsStatus | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [showTermsModal, setShowTermsModal] = useState(false);
  const [stripeLoading, setStripeLoading] = useState(false);
  const [payoutLoading, setPayoutLoading] = useState(false);
  const [payoutMessage, setPayoutMessage] = useState<string | null>(null);

  const load = useCallback(async () => {
    try {
      const [settingsRes, earningsRes, stripeRes, termsRes] =
        await Promise.all([
          fetch("/api/dashboard/operator/settings"),
          fetch("/api/dashboard/operator/earnings"),
          fetch("/api/stripe/connect/status"),
          fetch("/api/marketplace/terms"),
        ]);
      if (settingsRes.ok) setSettings(await settingsRes.json());
      if (earningsRes.ok) setEarnings(await earningsRes.json());
      if (stripeRes.ok) setStripeStatus(await stripeRes.json());
      if (termsRes.ok) setTermsStatus(await termsRes.json());
    } catch {
      // Settings may not exist yet
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    load();
  }, [load]);

  // Suppress lint -- userId reserved for future per-user keyed refresh
  void userId;

  // -------------------------------------------------------------------------
  // Handlers
  // -------------------------------------------------------------------------

  async function handleToggle() {
    if (!settings) return;

    // If enabling and terms not accepted, show modal instead
    if (!settings.marketplaceEnabled && !termsStatus?.accepted) {
      setShowTermsModal(true);
      return;
    }

    setSaving(true);
    try {
      const res = await fetch("/api/dashboard/operator/settings", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          marketplaceEnabled: !settings.marketplaceEnabled,
        }),
      });
      if (res.ok) {
        setSettings({
          ...settings,
          marketplaceEnabled: !settings.marketplaceEnabled,
        });
      }
    } finally {
      setSaving(false);
    }
  }

  async function handleAcceptTerms() {
    setSaving(true);
    try {
      const termsRes = await fetch("/api/marketplace/terms", {
        method: "POST",
      });
      if (!termsRes.ok) return;

      const termsData = await termsRes.json();
      setTermsStatus(termsData);

      // Now enable marketplace
      if (settings) {
        const settingsRes = await fetch("/api/dashboard/operator/settings", {
          method: "PUT",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ marketplaceEnabled: true }),
        });
        if (settingsRes.ok) {
          setSettings({ ...settings, marketplaceEnabled: true });
        }
      }
    } finally {
      setSaving(false);
      setShowTermsModal(false);
    }
  }

  async function handlePriceChange(price: number) {
    if (!settings) return;
    setSaving(true);
    try {
      const res = await fetch("/api/dashboard/operator/settings", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ pricePerMToken: price }),
      });
      if (res.ok) {
        setSettings({ ...settings, pricePerMToken: price });
      }
    } finally {
      setSaving(false);
    }
  }

  async function handleAutoPriceToggle() {
    if (!settings) return;
    setSaving(true);
    try {
      const res = await fetch("/api/dashboard/operator/settings", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ autoPrice: !settings.autoPrice }),
      });
      if (res.ok) {
        setSettings({ ...settings, autoPrice: !settings.autoPrice });
      }
    } finally {
      setSaving(false);
    }
  }

  async function handleStripeOnboard() {
    setStripeLoading(true);
    try {
      const res = await fetch("/api/stripe/connect/onboard", {
        method: "POST",
      });
      if (res.ok) {
        const data = await res.json();
        if (data.url) {
          window.location.href = data.url;
        }
      }
    } finally {
      setStripeLoading(false);
    }
  }

  async function handleStripeLoginLink() {
    setStripeLoading(true);
    try {
      const res = await fetch("/api/stripe/connect/login-link", {
        method: "POST",
      });
      if (res.ok) {
        const data = await res.json();
        if (data.url) {
          window.open(data.url, "_blank", "noopener,noreferrer");
        }
      }
    } finally {
      setStripeLoading(false);
    }
  }

  async function handleRequestPayout() {
    setPayoutLoading(true);
    setPayoutMessage(null);
    try {
      const res = await fetch("/api/stripe/connect/payout", {
        method: "POST",
      });
      const data = await res.json();
      if (res.ok) {
        setPayoutMessage(
          `Payout of $${data.amountDollars.toFixed(2)} initiated successfully.`,
        );
      } else {
        setPayoutMessage(data.error || "Payout request failed.");
      }
    } catch {
      setPayoutMessage("Failed to request payout. Please try again.");
    } finally {
      setPayoutLoading(false);
    }
  }

  // -------------------------------------------------------------------------
  // Computed values
  // -------------------------------------------------------------------------

  const dailyAvg =
    earnings && earnings.periodDays > 0
      ? earnings.operatorShare / earnings.periodDays
      : 0;
  const projectedMonthly = dailyAvg * 30;

  // First-booking cold-start signals (#503)
  // Show banner for 14 days after first booking so it doesn't become stale.
  const firstBookingDate = earnings?.firstBookingAt
    ? new Date(earnings.firstBookingAt)
    : null;
  const daysSinceFirstBooking = firstBookingDate
    ? (Date.now() - firstBookingDate.getTime()) / 86_400_000
    : null;
  const showFirstBookingBanner =
    firstBookingDate !== null && daysSinceFirstBooking !== null && daysSinceFirstBooking <= 14;
  // Stripe Connect standard: 7-day rolling payout for new accounts.
  const estimatedPayoutDate = firstBookingDate
    ? new Date(firstBookingDate.getTime() + 7 * 86_400_000)
    : null;

  // -------------------------------------------------------------------------
  // Render
  // -------------------------------------------------------------------------

  if (loading) {
    return (
      <div className="animate-pulse space-y-4">
        <div className="h-32 bg-gray-800 rounded-lg" />
        <div className="h-64 bg-gray-800 rounded-lg" />
      </div>
    );
  }

  return (
    <div className="space-y-6">
      {/* Terms Modal */}
      {showTermsModal && (
        <div
          className="fixed inset-0 z-50 flex items-center justify-center bg-black/60"
          data-testid="terms-modal"
        >
          <div className="relative w-full max-w-md rounded-xl border border-gray-800 bg-gray-900 p-6 shadow-2xl">
            <button
              onClick={() => setShowTermsModal(false)}
              className="absolute right-3 top-3 text-gray-400 hover:text-white"
              aria-label="Close terms modal"
            >
              <X className="h-5 w-5" />
            </button>

            <div className="flex items-center gap-2 mb-4">
              <Shield className="h-5 w-5 text-violet-400" />
              <h3 className="text-lg font-semibold">Marketplace Terms</h3>
            </div>

            <div className="space-y-3 text-sm text-gray-400 mb-6">
              <p>
                By enabling the marketplace, you agree to the following operator
                terms:
              </p>
              <ul className="list-disc list-inside space-y-1.5">
                <li>
                  You are sharing your GPU compute resources with marketplace
                  buyers.
                </li>
                <li>
                  Revenue is split 80/20 -- you keep 80% of each transaction.
                </li>
                <li>
                  You can disable marketplace sharing at any time with no
                  penalty.
                </li>
                <li>
                  There is no guaranteed minimum revenue. Earnings depend on
                  marketplace demand.
                </li>
                <li>
                  Payouts require a connected Stripe account and a minimum
                  balance of $1.00.
                </li>
              </ul>
            </div>

            <div className="flex gap-3">
              <button
                onClick={() => setShowTermsModal(false)}
                className="flex-1 rounded-lg border border-gray-700 bg-gray-800 px-4 py-2 text-sm font-medium hover:bg-gray-700 transition-colors"
              >
                Cancel
              </button>
              <button
                onClick={handleAcceptTerms}
                disabled={saving}
                data-testid="accept-terms-btn"
                className="flex-1 rounded-lg bg-violet-600 px-4 py-2 text-sm font-medium text-white hover:bg-violet-700 transition-colors disabled:opacity-50"
              >
                {saving ? (
                  <span className="flex items-center justify-center gap-1.5">
                    <Loader2 className="h-4 w-4 animate-spin" />
                    Accepting...
                  </span>
                ) : (
                  <span className="flex items-center justify-center gap-1.5">
                    <Check className="h-4 w-4" />
                    Accept & Enable
                  </span>
                )}
              </button>
            </div>
          </div>
        </div>
      )}

      {/* First-booking cold-start banner (#503) */}
      {showFirstBookingBanner && (
        <div
          className="rounded-lg border border-green-700/50 bg-green-950/30 p-4 flex items-start gap-3"
          data-testid="first-booking-banner"
        >
          <PartyPopper className="h-5 w-5 text-green-400 mt-0.5 shrink-0" />
          <div className="flex-1 min-w-0">
            <p className="text-sm font-semibold text-green-300">
              Your first booking arrived!
            </p>
            <p className="text-xs text-green-400/80 mt-0.5">
              Received{" "}
              {firstBookingDate?.toLocaleDateString(undefined, {
                month: "short",
                day: "numeric",
                hour: "2-digit",
                minute: "2-digit",
              })}
              {earnings && earnings.lifetimeRequests > 1 && (
                <> · {earnings.lifetimeRequests.toLocaleString()} requests served in total</>
              )}
            </p>
          </div>
          {estimatedPayoutDate && stripeStatus?.connected && (
            <div className="text-right shrink-0">
              <div className="flex items-center gap-1 text-xs text-gray-400">
                <Clock className="h-3.5 w-3.5" />
                <span>Est. first payout</span>
              </div>
              <p className="text-sm font-semibold text-white">
                {estimatedPayoutDate.toLocaleDateString(undefined, {
                  month: "short",
                  day: "numeric",
                })}
              </p>
            </div>
          )}
          {!stripeStatus?.connected && (
            <p className="text-xs text-yellow-400 shrink-0 self-center">
              Connect Stripe to receive payouts
            </p>
          )}
        </div>
      )}

      {/* Earnings Card */}
      {earnings && (
        <div className="rounded-lg border border-gray-800 bg-gray-900/50 p-6">
          <div className="flex items-center gap-2 mb-4">
            <DollarSign className="h-5 w-5 text-green-400" />
            <h2 className="text-lg font-semibold">Earnings</h2>
          </div>
          <div className="grid grid-cols-3 gap-4">
            <div>
              <p className="text-sm text-gray-400">Total Revenue</p>
              <p className="text-2xl font-bold" data-testid="total-revenue">
                ${earnings.totalRevenue.toFixed(2)}
              </p>
            </div>
            <div>
              <p className="text-sm text-gray-400">Your Share (80%)</p>
              <p
                className="text-2xl font-bold text-green-400"
                data-testid="operator-share"
              >
                ${earnings.operatorShare.toFixed(2)}
              </p>
            </div>
            <div>
              <p className="text-sm text-gray-400">Requests Served</p>
              <p className="text-2xl font-bold" data-testid="total-requests">
                {earnings.totalRequests.toLocaleString()}
              </p>
            </div>
          </div>

          {/* Earnings Projections */}
          {earnings.periodDays > 0 && (
            <div className="mt-4 pt-4 border-t border-gray-800">
              <div className="flex items-center gap-2 mb-3">
                <TrendingUp className="h-4 w-4 text-violet-400" />
                <p className="text-sm font-medium text-gray-300">
                  Earnings Trend ({earnings.periodDays}-day period)
                </p>
              </div>
              <div className="grid grid-cols-2 gap-4">
                <div className="rounded-md bg-gray-800/50 p-3">
                  <p className="text-xs text-gray-400">Daily Average</p>
                  <p
                    className="text-lg font-semibold"
                    data-testid="daily-average"
                  >
                    ${dailyAvg.toFixed(2)}
                  </p>
                </div>
                <div className="rounded-md bg-gray-800/50 p-3">
                  <p className="text-xs text-gray-400">Projected Monthly</p>
                  <p
                    className="text-lg font-semibold text-violet-400"
                    data-testid="projected-monthly"
                  >
                    ${projectedMonthly.toFixed(2)}
                  </p>
                </div>
              </div>
            </div>
          )}
        </div>
      )}

      {/* Settings Card */}
      <div className="rounded-lg border border-gray-800 bg-gray-900/50 p-6">
        <div className="flex items-center gap-2 mb-4">
          <Zap className="h-5 w-5 text-yellow-400" />
          <h2 className="text-lg font-semibold">Marketplace Settings</h2>
        </div>

        <div className="space-y-4">
          {/* Enable Toggle */}
          <div className="flex items-center justify-between">
            <div>
              <p className="font-medium">Share on Marketplace</p>
              <p className="text-sm text-gray-400">
                Allow others to use your GPU compute for a fee
              </p>
            </div>
            <button
              onClick={handleToggle}
              disabled={saving}
              role="switch"
              aria-checked={settings?.marketplaceEnabled ?? false}
              data-testid="marketplace-toggle"
              className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
                settings?.marketplaceEnabled ? "bg-green-500" : "bg-gray-600"
              }`}
            >
              <span
                className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
                  settings?.marketplaceEnabled
                    ? "translate-x-6"
                    : "translate-x-1"
                }`}
              />
            </button>
          </div>

          {/* Pricing (only when enabled) */}
          {settings?.marketplaceEnabled && (
            <>
              <div>
                <label
                  htmlFor="pricePerMToken"
                  className="block text-sm font-medium mb-1"
                >
                  Price per 1M tokens
                </label>
                <div className="flex items-center gap-2">
                  <span className="text-gray-400">$</span>
                  <input
                    id="pricePerMToken"
                    type="number"
                    step="0.01"
                    min="0.01"
                    max="1.00"
                    value={settings.pricePerMToken}
                    onChange={(e) =>
                      handlePriceChange(parseFloat(e.target.value) || 0.1)
                    }
                    className="w-24 rounded-md border border-gray-700 bg-gray-800 px-3 py-1.5 text-sm"
                  />
                  <span className="text-sm text-gray-400">/ 1M tokens</span>
                </div>
                <p className="text-xs text-gray-500 mt-1">
                  Platform takes 20% -- you keep $
                  {((settings.pricePerMToken || 0.1) * 0.8).toFixed(2)} per 1M
                  tokens
                </p>
              </div>

              <div className="flex items-center gap-2">
                <input
                  type="checkbox"
                  id="autoPrice"
                  checked={settings.autoPrice}
                  onChange={handleAutoPriceToggle}
                  className="rounded border-gray-700"
                />
                <label htmlFor="autoPrice" className="text-sm">
                  Auto-adjust pricing based on demand
                </label>
              </div>
            </>
          )}
        </div>
      </div>

      {/* Available Models (only when marketplace enabled) */}
      {settings?.marketplaceEnabled &&
        settings.availableModels.length > 0 && (
          <div className="rounded-lg border border-gray-800 bg-gray-900/50 p-6">
            <div className="flex items-center gap-2 mb-4">
              <Cpu className="h-5 w-5 text-blue-400" />
              <h2 className="text-lg font-semibold">Available Models</h2>
            </div>
            <p className="text-sm text-gray-400 mb-3">
              These models are available for marketplace requests from your
              device.
            </p>
            <div className="flex flex-wrap gap-2" data-testid="model-tags">
              {settings.availableModels.map((model) => (
                <span
                  key={model}
                  className="inline-flex items-center rounded-full bg-violet-600/20 border border-violet-500/30 px-3 py-1 text-xs font-medium text-violet-300"
                >
                  {model}
                </span>
              ))}
            </div>
          </div>
        )}

      {/* Stripe Connect Section */}
      <div
        className="rounded-lg border border-gray-800 bg-gray-900/50 p-6"
        data-testid="stripe-connect-section"
      >
        <div className="flex items-center gap-2 mb-4">
          <DollarSign className="h-5 w-5 text-violet-400" />
          <h2 className="text-lg font-semibold">Payouts</h2>
        </div>

        {stripeStatus?.connected ? (
          <div className="space-y-4">
            <div className="flex items-center gap-2">
              <span className="inline-flex items-center gap-1.5 rounded-full bg-green-500/20 border border-green-500/30 px-3 py-1 text-xs font-medium text-green-400">
                <Check className="h-3 w-3" />
                Connected
              </span>
              <span className="text-sm text-gray-400">
                Stripe account linked
              </span>
            </div>

            <div className="flex flex-wrap gap-3">
              <button
                onClick={handleStripeLoginLink}
                disabled={stripeLoading}
                data-testid="stripe-dashboard-btn"
                className="inline-flex items-center gap-1.5 rounded-lg bg-gray-800 px-4 py-2 text-sm font-medium hover:bg-gray-700 transition-colors disabled:opacity-50"
              >
                {stripeLoading ? (
                  <Loader2 className="h-4 w-4 animate-spin" />
                ) : (
                  <ExternalLink className="h-4 w-4" />
                )}
                View Stripe Dashboard
              </button>
              <button
                onClick={handleRequestPayout}
                disabled={payoutLoading}
                data-testid="request-payout-btn"
                className="inline-flex items-center gap-1.5 rounded-lg bg-violet-600 px-4 py-2 text-sm font-medium text-white hover:bg-violet-700 transition-colors disabled:opacity-50"
              >
                {payoutLoading ? (
                  <Loader2 className="h-4 w-4 animate-spin" />
                ) : (
                  <DollarSign className="h-4 w-4" />
                )}
                Request Payout
              </button>
            </div>

            {payoutMessage && (
              <p
                className={`text-sm ${
                  payoutMessage.includes("successfully")
                    ? "text-green-400"
                    : "text-amber-400"
                }`}
                data-testid="payout-message"
              >
                {payoutMessage}
              </p>
            )}
          </div>
        ) : (
          <div className="space-y-4">
            <div className="flex items-start gap-3">
              <AlertTriangle className="h-5 w-5 text-amber-400 mt-0.5 shrink-0" />
              <div>
                <p className="text-sm font-medium">
                  Connect your bank account to receive payouts
                </p>
                <p className="text-sm text-gray-400 mt-1">
                  Set up Stripe Connect to receive your 80% share of marketplace
                  earnings directly to your bank account.
                </p>
              </div>
            </div>
            <button
              onClick={handleStripeOnboard}
              disabled={stripeLoading}
              data-testid="stripe-onboard-btn"
              className="inline-flex items-center gap-1.5 rounded-lg bg-violet-600 px-4 py-2 text-sm font-medium text-white hover:bg-violet-700 transition-colors disabled:opacity-50"
            >
              {stripeLoading ? (
                <Loader2 className="h-4 w-4 animate-spin" />
              ) : (
                <ExternalLink className="h-4 w-4" />
              )}
              Set up Stripe
            </button>
          </div>
        )}
      </div>
    </div>
  );
}
