import { useEffect, useRef, useState } from "react";
import { Camera, Loader2, Trash2 } from "lucide-react";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import { supabase } from "@/integrations/supabase/client";
import { toast } from "sonner";

/**
 * Avatar uploader — upload, replace or remove the user's profile picture.
 * Files live in the public `avatars` bucket under `<user_id>/avatar.<ext>`.
 */
export function AvatarUploader({
  userId,
  email,
  displayName,
  lang,
}: {
  userId: string | null;
  email: string | null;
  displayName: string;
  lang: "en" | "zh";
}) {
  const [url, setUrl] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);
  const fileRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (!userId) return;
    let cancelled = false;
    supabase
      .from("user_preferences")
      .select("avatar_url")
      .eq("user_id", userId)
      .maybeSingle()
      .then(({ data }) => {
        if (!cancelled) setUrl((data?.avatar_url as string | null) ?? null);
      });
    return () => {
      cancelled = true;
    };
  }, [userId]);

  const initials = (displayName || email || "U")
    .split(/[\s@.]+/)
    .filter(Boolean)
    .slice(0, 2)
    .map((s) => s[0]?.toUpperCase())
    .join("") || "U";

  async function onPick(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    e.target.value = "";
    if (!file || !userId) return;
    if (file.size > 5 * 1024 * 1024) {
      toast.error(lang === "zh" ? "文件过大（最大5MB）" : "File too large (max 5MB)");
      return;
    }
    setBusy(true);
    try {
      const ext = (file.name.split(".").pop() || "jpg").toLowerCase();
      const path = `${userId}/avatar-${Date.now()}.${ext}`;
      const { error: upErr } = await supabase.storage
        .from("avatars")
        .upload(path, file, { upsert: true, contentType: file.type });
      if (upErr) throw upErr;
      const { data: pub } = supabase.storage.from("avatars").getPublicUrl(path);
      const publicUrl = pub.publicUrl;
      const { error: dbErr } = await supabase
        .from("user_preferences")
        .upsert(
          { user_id: userId, avatar_url: publicUrl },
          { onConflict: "user_id" },
        );
      if (dbErr) throw dbErr;
      setUrl(publicUrl);
      toast.success(lang === "zh" ? "头像已更新" : "Avatar updated");
    } catch (err) {
      toast.error(lang === "zh" ? "上传失败" : "Upload failed", {
        description: (err as Error).message,
      });
    } finally {
      setBusy(false);
    }
  }

  async function onRemove() {
    if (!userId) return;
    setBusy(true);
    try {
      const { error } = await supabase
        .from("user_preferences")
        .upsert(
          { user_id: userId, avatar_url: null },
          { onConflict: "user_id" },
        );
      if (error) throw error;
      setUrl(null);
      toast.success(lang === "zh" ? "已移除" : "Removed");
    } catch (err) {
      toast.error(lang === "zh" ? "操作失败" : "Failed", {
        description: (err as Error).message,
      });
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="flex items-center gap-4">
      <div className="relative">
        <Avatar className="h-20 w-20 ring-1 ring-border">
          {url ? <AvatarImage src={url} alt="" /> : null}
          <AvatarFallback className="bg-brand text-lg font-medium text-primary-foreground">
            {initials}
          </AvatarFallback>
        </Avatar>
        <button
          type="button"
          onClick={() => fileRef.current?.click()}
          disabled={busy || !userId}
          className="absolute -bottom-1 -right-1 flex h-7 w-7 items-center justify-center rounded-full bg-brand text-primary-foreground shadow ring-2 ring-card transition-transform hover:scale-105 disabled:opacity-60"
          aria-label={lang === "zh" ? "上传头像" : "Upload avatar"}
        >
          {busy ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Camera className="h-3.5 w-3.5" />}
        </button>
      </div>
      <div className="flex flex-col gap-2">
        <Button
          size="sm"
          variant="outline"
          onClick={() => fileRef.current?.click()}
          disabled={busy || !userId}
          className="gap-2"
        >
          <Camera className="h-4 w-4" />
          {lang === "zh" ? (url ? "更换照片" : "上传照片") : url ? "Change photo" : "Upload photo"}
        </Button>
        {url ? (
          <Button
            size="sm"
            variant="ghost"
            onClick={onRemove}
            disabled={busy}
            className="gap-2 text-destructive hover:text-destructive"
          >
            <Trash2 className="h-4 w-4" />
            {lang === "zh" ? "移除" : "Remove"}
          </Button>
        ) : null}
        <p className="text-[11px] text-muted-foreground">
          {lang === "zh" ? "JPG / PNG，最大 5MB" : "JPG or PNG, up to 5MB"}
        </p>
      </div>
      <input
        ref={fileRef}
        type="file"
        accept="image/png,image/jpeg,image/webp"
        className="hidden"
        onChange={onPick}
      />
    </div>
  );
}
