"use client";

import { useEffect, useState, useCallback, useRef } from "react";
import { bech32 } from "bech32";
import { api, ApiError } from "../api";
import { sharedStyles } from "../styles/shared";
import { Header } from "../components/Header";
import { useRequireAuth } from "../hooks/useRequireAuth";

interface ProfileData {
  contact_email: string | null;
  telegram: string | null;
  signal: string | null;
  nostr_npub: string | null;
}

interface FormData {
  contact_email: string;
  telegram: string;
  signal: string;
  nostr_npub: string;
}

interface FieldErrors {
  contact_email?: string;
  telegram?: string;
  signal?: string;
  nostr_npub?: string;
}

// Client-side validation matching backend rules
function validateEmail(value: string): string | undefined {
  if (!value) return undefined;
  // More comprehensive email regex that matches email-validator behavior
  // Checks for: local part, @, domain with at least one dot, valid TLD
  const emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/;
  if (!emailRegex.test(value)) {
    return "Please enter a valid email address";
  }
  return undefined;
}

function validateTelegram(value: string): string | undefined {
  if (!value) return undefined;
  if (!value.startsWith("@")) {
    return "Telegram handle must start with @";
  }
  const handle = value.slice(1);
  if (handle.length < 1) {
    return "Telegram handle must have at least one character after @";
  }
  if (handle.length > 32) {
    return "Telegram handle must be at most 32 characters (after @)";
  }
  return undefined;
}

function validateSignal(value: string): string | undefined {
  if (!value) return undefined;
  if (value.trim().length === 0) {
    return "Signal username cannot be empty";
  }
  if (value.length > 64) {
    return "Signal username must be at most 64 characters";
  }
  return undefined;
}

function validateNostrNpub(value: string): string | undefined {
  if (!value) return undefined;
  if (!value.startsWith("npub1")) {
    return "Nostr npub must start with 'npub1'";
  }
  
  try {
    const decoded = bech32.decode(value);
    if (decoded.prefix !== "npub") {
      return "Nostr npub must have 'npub' prefix";
    }
    // npub should decode to 32 bytes (256 bits) for a public key
    // In bech32, each character encodes 5 bits, so 32 bytes = 52 characters of data
    if (decoded.words.length !== 52) {
      return "Invalid Nostr npub: incorrect length";
    }
    return undefined;
  } catch {
    return "Invalid Nostr npub: bech32 checksum failed";
  }
}

function validateForm(data: FormData): FieldErrors {
  const errors: FieldErrors = {};
  const emailError = validateEmail(data.contact_email);
  if (emailError) errors.contact_email = emailError;
  const telegramError = validateTelegram(data.telegram);
  if (telegramError) errors.telegram = telegramError;
  const signalError = validateSignal(data.signal);
  if (signalError) errors.signal = signalError;
  const npubError = validateNostrNpub(data.nostr_npub);
  if (npubError) errors.nostr_npub = npubError;
  return errors;
}

function toFormData(data: ProfileData): FormData {
  return {
    contact_email: data.contact_email || "",
    telegram: data.telegram || "",
    signal: data.signal || "",
    nostr_npub: data.nostr_npub || "",
  };
}

export default function ProfilePage() {
  const { user, isLoading, isAuthorized } = useRequireAuth({
    requiredRole: "regular",
    fallbackRedirect: "/audit",
  });
  const [originalData, setOriginalData] = useState<FormData | null>(null);
  const [formData, setFormData] = useState<FormData>({
    contact_email: "",
    telegram: "",
    signal: "",
    nostr_npub: "",
  });
  const [errors, setErrors] = useState<FieldErrors>({});
  const [isLoadingProfile, setIsLoadingProfile] = useState(true);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [toast, setToast] = useState<{ message: string; type: "success" | "error" } | null>(null);
  const validationTimeoutRef = useRef<NodeJS.Timeout | null>(null);

  // Check if form has changes
  const hasChanges = useCallback(() => {
    if (!originalData) return false;
    return (
      formData.contact_email !== originalData.contact_email ||
      formData.telegram !== originalData.telegram ||
      formData.signal !== originalData.signal ||
      formData.nostr_npub !== originalData.nostr_npub
    );
  }, [formData, originalData]);

  // Check if form is valid
  const isValid = useCallback(() => {
    return Object.keys(errors).length === 0;
  }, [errors]);

  const fetchProfile = useCallback(async () => {
    try {
      const data = await api.get<ProfileData>("/api/profile");
      const formValues = toFormData(data);
      setFormData(formValues);
      setOriginalData(formValues);
    } catch (err) {
      console.error("Profile load error:", err);
      setToast({ message: "Failed to load profile", type: "error" });
    } finally {
      setIsLoadingProfile(false);
    }
  }, []);

  useEffect(() => {
    if (user && isAuthorized) {
      fetchProfile();
    }
  }, [user, isAuthorized, fetchProfile]);

  // Auto-dismiss toast after 3 seconds
  useEffect(() => {
    if (toast) {
      const timer = setTimeout(() => setToast(null), 3000);
      return () => clearTimeout(timer);
    }
  }, [toast]);

  // Cleanup validation timeout on unmount
  useEffect(() => {
    return () => {
      if (validationTimeoutRef.current) {
        clearTimeout(validationTimeoutRef.current);
      }
    };
  }, []);

  const handleInputChange = (field: keyof FormData) => (e: React.ChangeEvent<HTMLInputElement>) => {
    let value = e.target.value;
    
    // For telegram: auto-prepend @ if user starts with a valid letter
    if (field === "telegram" && value && !value.startsWith("@")) {
      // Check if first char is a valid telegram handle start (letter)
      if (/^[a-zA-Z]/.test(value)) {
        value = "@" + value;
      }
    }
    
    setFormData((prev) => ({ ...prev, [field]: value }));
    
    // Clear any pending validation timeout
    if (validationTimeoutRef.current) {
      clearTimeout(validationTimeoutRef.current);
    }
    
    // Debounce validation - wait 500ms after user stops typing
    validationTimeoutRef.current = setTimeout(() => {
      const newFormData = { ...formData, [field]: value };
      const newErrors = validateForm(newFormData);
      setErrors(newErrors);
    }, 500);
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    
    // Validate all fields
    const validationErrors = validateForm(formData);
    setErrors(validationErrors);
    
    if (Object.keys(validationErrors).length > 0) {
      return;
    }

    setIsSubmitting(true);

    try {
      const data = await api.put<ProfileData>("/api/profile", {
        contact_email: formData.contact_email || null,
        telegram: formData.telegram || null,
        signal: formData.signal || null,
        nostr_npub: formData.nostr_npub || null,
      });
      const formValues = toFormData(data);
      setFormData(formValues);
      setOriginalData(formValues);
      setToast({ message: "Profile saved successfully!", type: "success" });
    } catch (err) {
      console.error("Profile save error:", err);
      if (err instanceof ApiError && err.status === 422) {
        const errorData = err.data as { detail?: { field_errors?: FieldErrors } };
        if (errorData?.detail?.field_errors) {
          setErrors(errorData.detail.field_errors);
        }
        setToast({ message: "Please fix the errors below", type: "error" });
      } else {
        setToast({ message: "Network error. Please try again.", type: "error" });
      }
    } finally {
      setIsSubmitting(false);
    }
  };

  if (isLoading || isLoadingProfile) {
    return (
      <main style={styles.main}>
        <div style={styles.loader}>Loading...</div>
      </main>
    );
  }

  if (!user || !isAuthorized) {
    return null;
  }

  const canSubmit = hasChanges() && isValid() && !isSubmitting;

  return (
    <main style={styles.main}>
      {/* Toast notification */}
      {toast && (
        <div
          style={{
            ...styles.toast,
            ...(toast.type === "success" ? styles.toastSuccess : styles.toastError),
          }}
        >
          {toast.message}
        </div>
      )}

      <Header currentPage="profile" />

      <div style={styles.content}>
        <div style={styles.profileCard}>
          <div style={styles.cardHeader}>
            <h1 style={styles.cardTitle}>My Profile</h1>
            <p style={styles.cardSubtitle}>Manage your contact information</p>
          </div>

          <form onSubmit={handleSubmit} style={styles.form}>
            {/* Login email - read only */}
            <div style={styles.field}>
              <label style={styles.label}>
                Login Email
                <span style={styles.readOnlyBadge}>Read only</span>
              </label>
              <input
                type="email"
                value={user.email}
                style={{ ...styles.input, ...styles.inputReadOnly }}
                disabled
              />
              <span style={styles.hint}>
                This is your login email and cannot be changed here.
              </span>
            </div>

            <div style={styles.divider} />

            <p style={styles.sectionLabel}>Contact Details</p>
            <p style={styles.sectionHint}>
              These are for communication purposes only — they won&apos;t affect your login.
            </p>

            {/* Contact email */}
            <div style={styles.field}>
              <label htmlFor="contact_email" style={styles.label}>
                Contact Email
              </label>
              <input
                id="contact_email"
                type="email"
                value={formData.contact_email}
                onChange={handleInputChange("contact_email")}
                style={{
                  ...styles.input,
                  ...(errors.contact_email ? styles.inputError : {}),
                }}
                placeholder="alternate@example.com"
              />
              {errors.contact_email && (
                <span style={styles.errorText}>{errors.contact_email}</span>
              )}
            </div>

            {/* Telegram */}
            <div style={styles.field}>
              <label htmlFor="telegram" style={styles.label}>
                Telegram
              </label>
              <input
                id="telegram"
                type="text"
                value={formData.telegram}
                onChange={handleInputChange("telegram")}
                style={{
                  ...styles.input,
                  ...(errors.telegram ? styles.inputError : {}),
                }}
                placeholder="@username"
              />
              {errors.telegram && (
                <span style={styles.errorText}>{errors.telegram}</span>
              )}
            </div>

            {/* Signal */}
            <div style={styles.field}>
              <label htmlFor="signal" style={styles.label}>
                Signal
              </label>
              <input
                id="signal"
                type="text"
                value={formData.signal}
                onChange={handleInputChange("signal")}
                style={{
                  ...styles.input,
                  ...(errors.signal ? styles.inputError : {}),
                }}
                placeholder="username.01"
              />
              {errors.signal && (
                <span style={styles.errorText}>{errors.signal}</span>
              )}
            </div>

            {/* Nostr npub */}
            <div style={styles.field}>
              <label htmlFor="nostr_npub" style={styles.label}>
                Nostr (npub)
              </label>
              <input
                id="nostr_npub"
                type="text"
                value={formData.nostr_npub}
                onChange={handleInputChange("nostr_npub")}
                style={{
                  ...styles.input,
                  ...(errors.nostr_npub ? styles.inputError : {}),
                }}
                placeholder="npub1..."
              />
              {errors.nostr_npub && (
                <span style={styles.errorText}>{errors.nostr_npub}</span>
              )}
            </div>

            <button
              type="submit"
              style={{
                ...styles.button,
                ...(!canSubmit ? styles.buttonDisabled : {}),
              }}
              disabled={!canSubmit}
            >
              {isSubmitting ? "Saving..." : "Save Changes"}
            </button>
          </form>
        </div>
      </div>
    </main>
  );
}

const pageStyles: Record<string, React.CSSProperties> = {
  profileCard: {
    background: "rgba(255, 255, 255, 0.03)",
    backdropFilter: "blur(10px)",
    border: "1px solid rgba(255, 255, 255, 0.08)",
    borderRadius: "24px",
    padding: "2.5rem",
    width: "100%",
    maxWidth: "480px",
    boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.5)",
  },
  cardHeader: {
    marginBottom: "2rem",
  },
  cardTitle: {
    fontFamily: "'Instrument Serif', Georgia, serif",
    fontSize: "2rem",
    fontWeight: 400,
    color: "#fff",
    margin: 0,
    letterSpacing: "-0.02em",
  },
  cardSubtitle: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    color: "rgba(255, 255, 255, 0.5)",
    marginTop: "0.5rem",
    fontSize: "0.95rem",
  },
  form: {
    display: "flex",
    flexDirection: "column",
    gap: "1.25rem",
  },
  field: {
    display: "flex",
    flexDirection: "column",
    gap: "0.5rem",
  },
  label: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    color: "rgba(255, 255, 255, 0.7)",
    fontSize: "0.875rem",
    fontWeight: 500,
    display: "flex",
    alignItems: "center",
    gap: "0.5rem",
  },
  readOnlyBadge: {
    fontSize: "0.7rem",
    fontWeight: 500,
    color: "rgba(255, 255, 255, 0.4)",
    background: "rgba(255, 255, 255, 0.08)",
    padding: "0.15rem 0.5rem",
    borderRadius: "4px",
    textTransform: "uppercase",
    letterSpacing: "0.05em",
  },
  input: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    padding: "0.875rem 1rem",
    fontSize: "1rem",
    background: "rgba(255, 255, 255, 0.05)",
    border: "1px solid rgba(255, 255, 255, 0.1)",
    borderRadius: "12px",
    color: "#fff",
    outline: "none",
    transition: "border-color 0.2s, box-shadow 0.2s",
  },
  inputReadOnly: {
    background: "rgba(255, 255, 255, 0.02)",
    color: "rgba(255, 255, 255, 0.5)",
    cursor: "not-allowed",
  },
  inputError: {
    border: "1px solid rgba(239, 68, 68, 0.5)",
    boxShadow: "0 0 0 2px rgba(239, 68, 68, 0.1)",
  },
  hint: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    fontSize: "0.75rem",
    color: "rgba(255, 255, 255, 0.4)",
    fontStyle: "italic",
  },
  errorText: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    fontSize: "0.75rem",
    color: "#fca5a5",
  },
  divider: {
    height: "1px",
    background: "rgba(255, 255, 255, 0.08)",
    margin: "0.75rem 0",
  },
  sectionLabel: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    fontSize: "0.875rem",
    fontWeight: 600,
    color: "rgba(255, 255, 255, 0.8)",
    margin: 0,
    textTransform: "uppercase",
    letterSpacing: "0.05em",
  },
  sectionHint: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    fontSize: "0.8rem",
    color: "rgba(255, 255, 255, 0.4)",
    margin: 0,
    marginBottom: "0.5rem",
  },
  button: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    marginTop: "1rem",
    padding: "1rem",
    fontSize: "1rem",
    fontWeight: 600,
    background: "linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)",
    color: "#fff",
    border: "none",
    borderRadius: "12px",
    cursor: "pointer",
    transition: "transform 0.2s, box-shadow 0.2s",
    boxShadow: "0 4px 14px rgba(99, 102, 241, 0.4)",
  },
  buttonDisabled: {
    opacity: 0.5,
    cursor: "not-allowed",
    boxShadow: "none",
  },
  toast: {
    position: "fixed",
    top: "1.5rem",
    right: "1.5rem",
    padding: "1rem 1.5rem",
    borderRadius: "12px",
    fontFamily: "'DM Sans', system-ui, sans-serif",
    fontSize: "0.875rem",
    fontWeight: 500,
    zIndex: 1000,
    animation: "slideIn 0.3s ease-out",
    boxShadow: "0 10px 25px rgba(0, 0, 0, 0.3)",
  },
  toastSuccess: {
    background: "rgba(34, 197, 94, 0.9)",
    color: "#fff",
  },
  toastError: {
    background: "rgba(239, 68, 68, 0.9)",
    color: "#fff",
  },
};

const styles = { ...sharedStyles, ...pageStyles };
