import { useState } from "react";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/shared/common/ui/card";
import { Input } from "@/shared/common/ui/input";
import { Button } from "@/shared/common/ui/button";
import { AlertTriangle, CheckCircle2, RefreshCw, Save } from "lucide-react";

import {
  useExchangeSettingsQuery,
  useSetExchangeFallbackRate,
} from "@/hooks/useExchangeSettings";
import type { ExchangeRateSource } from "@/services/exchangeSettings.service";

/** Feed health, phrased for an operator rather than a developer. */
function feedLabel(source: ExchangeRateSource | null): {
  live: boolean;
  text: string;
} {
  switch (source) {
    case "live":
      return { live: true, text: "CBE reachable — using the live rate" };
    case "stored":
      return {
        live: false,
        text: "CBE unreachable — using the fallback rate below",
      };
    default:
      return { live: true, text: "No rate requested yet since the last restart" };
  }
}

const formatTime = (value: string | null) =>
  value ? new Date(value).toLocaleString() : "never";

/**
 * USD→ETB fallback used when the CBE exchange-rate endpoint is unreachable.
 * The live CBE rate always wins; every successful fetch overwrites the stored
 * value, so it tracks the last known good rate on its own. Editing here is for
 * a prolonged outage — the next successful CBE fetch replaces it.
 */
export default function ExchangeRateSettingsCard() {
  const { data, isLoading, refetch, isFetching } = useExchangeSettingsQuery();
  const setRate = useSetExchangeFallbackRate();
  const [draft, setDraft] = useState<string>("");

  const value = draft !== "" ? draft : (data?.fallbackRate?.toString() ?? "");
  const parsed = Number(value);
  const invalid = !Number.isFinite(parsed) || parsed < 1 || parsed > 10_000;
  const dirty = draft !== "" && parsed !== data?.fallbackRate;

  const feed = feedLabel(data?.feed?.source ?? null);

  const handleSave = async () => {
    if (invalid) return;
    await setRate.mutateAsync(parsed);
    setDraft("");
  };

  return (
    <Card className="shadow-lg border-gray-200 dark:border-gray-700">
      <CardHeader>
        <div className="flex items-start justify-between gap-4">
          <div>
            <CardTitle>Exchange rate (USD → ETB)</CardTitle>
            <CardDescription>
              Rates come from the Commercial Bank of Ethiopia. The fallback
              below is used only when CBE cannot be reached, and is refreshed
              automatically after every successful update.
            </CardDescription>
          </div>
          <Button
            variant="outline"
            size="sm"
            onClick={() => refetch()}
            disabled={isFetching}
          >
            <RefreshCw
              className={`h-4 w-4 ${isFetching ? "animate-spin" : ""}`}
            />
          </Button>
        </div>
      </CardHeader>

      <CardContent className="space-y-4">
        <div
          className={`flex items-start gap-2 rounded-md border p-3 text-sm ${
            feed.live
              ? "border-green-200 bg-green-50 text-green-900 dark:border-green-900 dark:bg-green-950 dark:text-green-100"
              : "border-amber-200 bg-amber-50 text-amber-900 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-100"
          }`}
        >
          {feed.live ? (
            <CheckCircle2 className="mt-0.5 h-4 w-4 shrink-0" />
          ) : (
            <AlertTriangle className="mt-0.5 h-4 w-4 shrink-0" />
          )}
          <div className="space-y-1">
            <p className="font-medium">{feed.text}</p>
            {data?.feed?.rate != null && (
              <p>Rate in use: {data.feed.rate} ETB per USD</p>
            )}
            <p className="opacity-80">
              Last successful update: {formatTime(data?.feed?.lastSuccessAt ?? null)}
            </p>
            {data?.feed?.lastError && (
              <p className="opacity-80">Last error: {data.feed.lastError}</p>
            )}
          </div>
        </div>

        <div className="space-y-2">
          <label className="text-sm font-medium" htmlFor="fallback-rate">
            Fallback rate (ETB per USD)
          </label>
          <div className="flex items-center gap-2">
            <Input
              id="fallback-rate"
              type="number"
              step="0.0001"
              min={1}
              max={10000}
              className="max-w-[220px]"
              disabled={isLoading}
              value={value}
              onChange={(e) => setDraft(e.target.value)}
            />
            <Button
              onClick={handleSave}
              disabled={!dirty || invalid || setRate.isPending}
            >
              <Save className="mr-2 h-4 w-4" />
              Save
            </Button>
          </div>
          {invalid && draft !== "" && (
            <p className="text-sm text-red-600">
              Enter a rate between 1 and 10,000.
            </p>
          )}
          <p className="text-sm text-muted-foreground">
            {data?.fallbackSource === "MANUAL"
              ? "Set manually. The next successful CBE update will replace it."
              : `Synced automatically from CBE (${formatTime(
                  data?.lastSyncedAt ?? null,
                )}).`}
          </p>
        </div>
      </CardContent>
    </Card>
  );
}
