"use client";

import { useEffect, useState, useCallback, useRef } from "react";

import { api, ApiError } from "../api";
import { Permission } from "../auth-context";
import { Header } from "../components/Header";
import { components } from "../generated/api";
import { useRequireAuth } from "../hooks/useRequireAuth";
import {
  layoutStyles,
  cardStyles,
  formStyles,
  buttonStyles,
  toastStyles,
  utilityStyles,
} from "../styles/shared";
import { FieldErrors, validateProfileFields } from "../utils/validation";

// Use generated type from OpenAPI schema
type ProfileData = components["schemas"]["ProfileResponse"];

// UI-specific types (not from API)
interface FormData {
  contact_email: string;
  telegram: string;
  signal: string;
  nostr_npub: string;
}

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({
    requiredPermission: Permission.MANAGE_OWN_PROFILE,
    fallbackRedirect: "/audit",
  });
  const [originalData, setOriginalData] = useState<FormData | null>(null);
  const [formData, setFormData] = useState<FormData>({
    contact_email: "",
    telegram: "",
    signal: "",
    nostr_npub: "",
  });
  const [godfatherEmail, setGodfatherEmail] = useState<string | null>(null);
  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);
      setGodfatherEmail(data.godfather_email ?? null);
    } 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 = validateProfileFields(newFormData);
      setErrors(newErrors);
    }, 500);
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    // Validate all fields
    const validationErrors = validateProfileFields(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={layoutStyles.main}>
        <div style={layoutStyles.loader}>Loading...</div>
      </main>
    );
  }

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

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

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

      <Header currentPage="profile" />

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

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

            {/* Godfather - shown if user was invited */}
            {godfatherEmail && (
              <div style={formStyles.field}>
                <label style={styles.labelWithBadge}>
                  Invited By
                  <span style={utilityStyles.readOnlyBadge}>Read only</span>
                </label>
                <div style={styles.godfatherBox}>
                  <span style={styles.godfatherEmail}>{godfatherEmail}</span>
                </div>
                <span style={formStyles.hint}>The user who invited you to join.</span>
              </div>
            )}

            <div style={utilityStyles.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={formStyles.field}>
              <label htmlFor="contact_email" style={formStyles.label}>
                Contact Email
              </label>
              <input
                id="contact_email"
                type="email"
                value={formData.contact_email}
                onChange={handleInputChange("contact_email")}
                style={{
                  ...formStyles.input,
                  ...(errors.contact_email ? formStyles.inputError : {}),
                }}
                placeholder="alternate@example.com"
              />
              {errors.contact_email && (
                <span style={formStyles.errorText}>{errors.contact_email}</span>
              )}
            </div>

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

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

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

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

// Page-specific styles
const styles: Record<string, React.CSSProperties> = {
  profileCard: {
    ...cardStyles.card,
    width: "100%",
    maxWidth: "480px",
  },
  labelWithBadge: {
    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",
  },
  godfatherBox: {
    padding: "0.875rem 1rem",
    background: "rgba(99, 102, 241, 0.08)",
    border: "1px solid rgba(99, 102, 241, 0.2)",
    borderRadius: "12px",
  },
  godfatherEmail: {
    fontFamily: "'DM Sans', system-ui, sans-serif",
    fontSize: "1rem",
    color: "rgba(129, 140, 248, 0.9)",
  },
  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",
  },
};
