import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { History, Loader, RotateCcw } from "lucide-react";
import { toast } from "sonner";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from "@/shared/common/ui/dialog";
import { TemplateService } from "@/user-management/services/api/templateService";
import {
  TemplateSampleSetting,
  TemplateSettingValueHistoryEntry,
} from "@/user-management/services/TemplateConfiguration/types/templateTypes";

type SettingHistoryModalProps = {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  setting: TemplateSampleSetting | null;
  unitId?: string;
  onRestored: () => void | Promise<void>;
};

const formatTimestamp = (value?: string) => {
  if (!value) return "—";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  return date.toLocaleString();
};

export const SettingHistoryModal: React.FC<SettingHistoryModalProps> = ({
  open,
  onOpenChange,
  setting,
  unitId,
  onRestored,
}) => {
  const { t } = useTranslation();
  const [items, setItems] = useState<TemplateSettingValueHistoryEntry[]>([]);
  const [loading, setLoading] = useState(false);
  const [restoringId, setRestoringId] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  const loadHistory = useCallback(async () => {
    if (!setting?.id || !unitId) return;

    try {
      setLoading(true);
      setError(null);
      const response = await TemplateService.getTemplateSettingValueHistory(
        setting.id,
        unitId,
      );
      setItems(response.items ?? []);
    } catch (err) {
      const message =
        err instanceof Error
          ? err.message
          : t("template.historyLoadFailed", "Failed to load setting history");
      setError(message);
      setItems([]);
    } finally {
      setLoading(false);
    }
  }, [setting?.id, unitId, t]);

  useEffect(() => {
    if (open) {
      void loadHistory();
    } else {
      setItems([]);
      setError(null);
      setRestoringId(null);
    }
  }, [open, loadHistory]);

  const handleRestore = async (historyId: string) => {
    if (!setting?.id || !unitId) return;

    try {
      setRestoringId(historyId);
      await TemplateService.restoreTemplateSettingFromHistory(
        setting.id,
        historyId,
        unitId,
      );
      toast.success(
        t("template.historyRestored", "Setting restored from history"),
      );
      await onRestored();
      onOpenChange(false);
    } catch (err) {
      const message =
        err instanceof Error
          ? err.message
          : t("template.historyRestoreFailed", "Failed to restore setting");
      toast.error(message);
    } finally {
      setRestoringId(null);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-h-[80vh] max-w-2xl overflow-hidden">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <History className="h-5 w-5 text-purple-600" />
            {t("template.settingHistory", "Setting History")}
          </DialogTitle>
        </DialogHeader>

        {setting ? (
          <p className="text-sm text-gray-500 dark:text-gray-400">
            {setting.code}
          </p>
        ) : null}

        {loading ? (
          <div className="flex items-center justify-center py-10">
            <Loader className="h-6 w-6 animate-spin text-purple-600" />
          </div>
        ) : error ? (
          <div className="rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-800 dark:bg-red-900/20 dark:text-red-300">
            {error}
          </div>
        ) : items.length === 0 ? (
          <p className="py-8 text-center text-sm text-gray-500 dark:text-gray-400">
            {t("template.noHistory", "No history entries for this setting.")}
          </p>
        ) : (
          <div className="max-h-[50vh] space-y-3 overflow-y-auto pr-1">
            {items.map((entry) => (
              <div
                key={entry.id}
                className="rounded-lg border border-gray-200 p-4 dark:border-gray-700"
              >
                <div className="mb-2 flex flex-wrap items-center justify-between gap-2">
                  <div className="text-sm text-gray-600 dark:text-gray-300">
                    {formatTimestamp(entry.createdAt || entry.updatedAt)}
                  </div>
                  <button
                    type="button"
                    onClick={() => void handleRestore(entry.id)}
                    disabled={restoringId === entry.id}
                    className="inline-flex items-center gap-1 rounded-md border border-purple-200 px-2.5 py-1 text-xs font-medium text-purple-700 transition-colors hover:bg-purple-50 disabled:cursor-not-allowed disabled:opacity-50 dark:border-purple-800 dark:text-purple-300 dark:hover:bg-purple-900/30"
                  >
                    {restoringId === entry.id ? (
                      <Loader className="h-3.5 w-3.5 animate-spin" />
                    ) : (
                      <RotateCcw className="h-3.5 w-3.5" />
                    )}
                    {t("template.restoreVersion", "Restore")}
                  </button>
                </div>
                <pre className="overflow-x-auto rounded-md bg-gray-50 p-3 text-xs text-gray-700 dark:bg-gray-900 dark:text-gray-200">
                  {JSON.stringify(entry.value ?? {}, null, 2)}
                </pre>
              </div>
            ))}
          </div>
        )}
      </DialogContent>
    </Dialog>
  );
};
