import { useEffect, useMemo, useState } from "react";
import { createPortal } from "react-dom";
import { useTranslation } from "react-i18next";
import { useLocation } from "react-router-dom";
import { X, MessageSquarePlus, CheckCircle, AlertCircle } from "lucide-react";
import { useFeedback } from "../../hooks/useFeedback";
import { useAuth } from "../../hooks/useAuth";
import { getRecentErrorLogs } from "../../services/logService";
import {
  getFeedbackUserAgent,
  type FeedbackContext,
} from "../../services/feedbackService";

const MAX_CONTENT_LENGTH = 2000;
const LOGS_SUFFIX_MAX = 800;
const RECENT_ERROR_LOGS_N = 20;
const AUTO_CLOSE_DELAY_MS = 2000;

interface FeedbackDialogProps {
  onClose: () => void;
}

export default function FeedbackDialog({ onClose }: FeedbackDialogProps) {
  const { t, i18n } = useTranslation();
  const location = useLocation();
  const { state: authState } = useAuth();
  const { state: feedbackState, submit, reset } = useFeedback();

  const [content, setContent] = useState("");
  const [includeContext, setIncludeContext] = useState(false);
  const [includeLogs, setIncludeLogs] = useState(false);
  const [identify, setIdentify] = useState(false);

  const isAuthenticated = authState.status === "authenticated";
  const userEmail = authState.account?.email ?? null;

  const trimmed = content.trim();
  const isSending = feedbackState.status === "sending";
  const isSuccess = feedbackState.status === "success";
  const canSubmit = trimmed.length > 0 && !isSending && !isSuccess;

  useEffect(() => {
    function handleEscape(e: KeyboardEvent) {
      if (e.key === "Escape" && !isSending) onClose();
    }
    document.addEventListener("keydown", handleEscape);
    return () => document.removeEventListener("keydown", handleEscape);
  }, [onClose, isSending]);

  // Auto-close after success
  useEffect(() => {
    if (!isSuccess) return;
    const timer = setTimeout(() => {
      onClose();
      reset();
    }, AUTO_CLOSE_DELAY_MS);
    return () => clearTimeout(timer);
  }, [isSuccess, onClose, reset]);

  const errorMessage = useMemo(() => {
    if (feedbackState.status !== "error" || !feedbackState.errorCode) return null;
    switch (feedbackState.errorCode) {
      case "rate_limit":
        return t("feedback.toast.error.429");
      case "invalid":
        return t("feedback.toast.error.400");
      case "network_error":
      case "server_error":
      default:
        return t("feedback.toast.error.generic");
    }
  }, [feedbackState, t]);

  async function handleSubmit() {
    if (!canSubmit) return;

    // Compose content with optional logs suffix, keeping total ≤ 2000 chars
    let body = trimmed;
    if (includeLogs) {
      const rawLogs = getRecentErrorLogs(RECENT_ERROR_LOGS_N);
      if (rawLogs.length > 0) {
        const trimmedLogs = rawLogs.slice(-LOGS_SUFFIX_MAX);
        const suffix = `\n\n---\n${t("feedback.logsHeading")}\n${trimmedLogs}`;
        const available = MAX_CONTENT_LENGTH - body.length;
        if (available > suffix.length) {
          body = body + suffix;
        } else if (available > 50) {
          body = body + suffix.slice(0, available);
        }
      }
    }

    // Compose context if opted in
    let context: FeedbackContext | undefined;
    if (includeContext) {
      let userAgent = "Simpl'Résultat";
      try {
        userAgent = await getFeedbackUserAgent();
      } catch {
        // fall back to a basic string if the Rust helper fails
      }
      context = {
        page: location.pathname,
        locale: i18n.language,
        theme: document.documentElement.classList.contains("dark") ? "dark" : "light",
        viewport: `${window.innerWidth}x${window.innerHeight}`,
        userAgent,
        timestamp: new Date().toISOString(),
      };
    }

    const userId = identify && isAuthenticated ? userEmail : null;

    await submit({ content: body, userId, context });
  }

  return createPortal(
    <div
      className="fixed inset-0 z-[200] flex items-center justify-center bg-black/50"
      onClick={(e) => {
        if (e.target === e.currentTarget && !isSending) onClose();
      }}
    >
      <div className="bg-[var(--card)] rounded-xl border border-[var(--border)] shadow-2xl w-full max-w-lg mx-4">
        <div className="flex items-center justify-between px-6 py-4 border-b border-[var(--border)]">
          <h2 className="text-lg font-semibold flex items-center gap-2">
            <MessageSquarePlus size={18} />
            {t("feedback.dialog.title")}
          </h2>
          <button
            onClick={onClose}
            disabled={isSending}
            className="text-[var(--muted-foreground)] hover:text-[var(--foreground)] disabled:opacity-50"
            aria-label={t("feedback.dialog.cancel")}
          >
            <X size={18} />
          </button>
        </div>

        <div className="px-6 py-4 space-y-3">
          {isSuccess ? (
            <div className="flex items-center gap-2 text-[var(--positive)] py-8 justify-center">
              <CheckCircle size={20} />
              <span>{t("feedback.toast.success")}</span>
            </div>
          ) : (
            <>
              <textarea
                value={content}
                onChange={(e) =>
                  setContent(e.target.value.slice(0, MAX_CONTENT_LENGTH))
                }
                placeholder={t("feedback.dialog.placeholder")}
                rows={6}
                disabled={isSending}
                className="w-full px-3 py-2 rounded-lg bg-[var(--background)] border border-[var(--border)] text-sm resize-y focus:outline-none focus:ring-2 focus:ring-[var(--primary)] disabled:opacity-50"
              />
              <div className="flex justify-end text-xs text-[var(--muted-foreground)]">
                {content.length}/{MAX_CONTENT_LENGTH}
              </div>

              <div className="space-y-2 text-sm">
                <label className="flex items-center gap-2 cursor-pointer">
                  <input
                    type="checkbox"
                    checked={includeContext}
                    onChange={(e) => setIncludeContext(e.target.checked)}
                    disabled={isSending}
                    className="h-4 w-4"
                  />
                  <span>{t("feedback.checkbox.context")}</span>
                </label>
                <label className="flex items-center gap-2 cursor-pointer">
                  <input
                    type="checkbox"
                    checked={includeLogs}
                    onChange={(e) => setIncludeLogs(e.target.checked)}
                    disabled={isSending}
                    className="h-4 w-4"
                  />
                  <span>{t("feedback.checkbox.logs")}</span>
                </label>
                {isAuthenticated && (
                  <label className="flex items-center gap-2 cursor-pointer">
                    <input
                      type="checkbox"
                      checked={identify}
                      onChange={(e) => setIdentify(e.target.checked)}
                      disabled={isSending}
                      className="h-4 w-4"
                    />
                    <span>
                      {t("feedback.checkbox.identify")}
                      {userEmail && (
                        <span className="text-[var(--muted-foreground)]">
                          {" "}
                          ({userEmail})
                        </span>
                      )}
                    </span>
                  </label>
                )}
              </div>

              {errorMessage && (
                <div className="flex items-start gap-2 text-sm text-[var(--negative)]">
                  <AlertCircle size={16} className="mt-0.5 shrink-0" />
                  <span>{errorMessage}</span>
                </div>
              )}
            </>
          )}
        </div>

        {!isSuccess && (
          <div className="flex justify-end gap-2 px-6 py-4 border-t border-[var(--border)]">
            <button
              onClick={onClose}
              disabled={isSending}
              className="px-4 py-2 text-sm border border-[var(--border)] rounded-lg hover:bg-[var(--border)] transition-colors disabled:opacity-50"
            >
              {t("feedback.dialog.cancel")}
            </button>
            <button
              onClick={handleSubmit}
              disabled={!canSubmit}
              className="px-4 py-2 text-sm bg-[var(--primary)] text-[var(--primary-foreground)] rounded-lg hover:opacity-90 transition-opacity disabled:opacity-50"
            >
              {isSending
                ? t("feedback.dialog.sending")
                : t("feedback.dialog.submit")}
            </button>
          </div>
        )}
      </div>
    </div>,
    document.body,
  );
}
