import { useEffect, useRef, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { useQueryClient } from "@tanstack/react-query";
import { useForm } from "react-hook-form";
import { FiArrowLeft, FiImage, FiTrash2, FiPlus, FiX } from "react-icons/fi";
import {
  useApiSocialHubsRetrieve,
  getApiSocialHubsRetrieveQueryKey,
  useApiSocialHubsPartialUpdate,
  useApiSocialHubsDestroy,
  useApiSocialHubsModeratorsList,
  getApiSocialHubsModeratorsListQueryKey,
  useApiSocialHubsModeratorsCreate,
  useApiSocialHubsModeratorsPartialUpdate,
  useApiSocialHubsModeratorsDestroy,
  useApiSocialHubsTagsList,
  getApiSocialHubsTagsListQueryKey,
  useApiSocialHubsTagsCreate,
  useApiSocialHubsTagsDestroy,
} from "@/api/generated/private/hubs/hubs";
import { useAuth } from "@/hooks/useAuth";
import Button from "@/components/ui/Button";
import Spinner from "@/components/ui/Spinner";
import EmptyState from "@/components/ui/EmptyState";
import Avatar from "@/components/ui/Avatar";

type Tab = "general" | "moderators" | "tags";

// ---------------------------------------------------------------------------
// General tab
// ---------------------------------------------------------------------------
interface GeneralForm {
  name: string;
  description: string;
  is_public: boolean;
}

function GeneralTab({ hubId: _hubId, hubName }: { hubId: number; hubName: string }) {
  const { t } = useTranslation("social");
  const queryClient = useQueryClient();
  const { data: hub } = useApiSocialHubsRetrieve(hubName);
  const [icon, setIcon] = useState<File | null>(null);
  const [banner, setBanner] = useState<File | null>(null);
  const [iconPreview, setIconPreview] = useState<string | null>(null);
  const [bannerPreview, setBannerPreview] = useState<string | null>(null);
  const iconRef = useRef<HTMLInputElement>(null);
  const bannerRef = useRef<HTMLInputElement>(null);

  const { register, handleSubmit, reset } = useForm<GeneralForm>();

  useEffect(() => {
    if (hub) reset({ name: hub.name, description: hub.description ?? "", is_public: hub.is_public });
  }, [hub, reset]);

  const mutation = useApiSocialHubsPartialUpdate({
    mutation: {
      onSuccess: () => {
        void queryClient.invalidateQueries({ queryKey: getApiSocialHubsRetrieveQueryKey(hubName) });
      },
    },
  });

  function pickFile(setter: (f: File) => void, previewSetter: (s: string) => void) {
    return (e: React.ChangeEvent<HTMLInputElement>) => {
      const f = e.target.files?.[0];
      if (!f) return;
      setter(f);
      previewSetter(URL.createObjectURL(f));
    };
  }

  async function onSubmit(values: GeneralForm) {
    const form = new FormData();
    form.append("name", values.name);
    form.append("description", values.description);
    form.append("is_public", String(values.is_public));
    if (icon) form.append("icon", icon);
    if (banner) form.append("banner", banner);
    mutation.mutate({ name: hubName, data: form as unknown as Parameters<typeof mutation.mutate>[0]["data"] });
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="flex flex-col gap-5 py-4">
      {/* Banner */}
      <div>
        <label className="mb-1 block text-xs font-medium text-brand-text/60">{t("hubSettings.bannerLabel")}</label>
        <button type="button" onClick={() => bannerRef.current?.click()}
          className="relative flex h-28 w-full items-center justify-center overflow-hidden rounded-xl border-2 border-dashed border-brand-lines/30 bg-brand-bgLight/30 text-brand-text/40 hover:border-brand-accent/40 hover:text-brand-accent/60 transition-colors">
          {bannerPreview || hub?.banner
            ? <img src={bannerPreview ?? hub?.banner ?? undefined} alt="" className="h-full w-full object-cover" />
            : <span className="flex flex-col items-center gap-1 text-xs"><FiImage size={22} />{t("hubSettings.changeBanner")}</span>}
        </button>
        <input ref={bannerRef} type="file" accept="image/*" className="hidden" onChange={pickFile(setBanner, setBannerPreview)} />
      </div>

      {/* Icon */}
      <div>
        <label className="mb-1 block text-xs font-medium text-brand-text/60">{t("hubSettings.iconLabel")}</label>
        <button type="button" onClick={() => iconRef.current?.click()}
          className="relative flex h-20 w-20 items-center justify-center overflow-hidden rounded-full border-2 border-dashed border-brand-lines/30 bg-brand-bgLight/30 text-brand-text/40 hover:border-brand-accent/40 hover:text-brand-accent/60 transition-colors">
          {iconPreview || hub?.icon
            ? <img src={iconPreview ?? hub?.icon ?? undefined} alt="" className="h-full w-full object-cover rounded-full" />
            : <FiImage size={20} />}
        </button>
        <input ref={iconRef} type="file" accept="image/*" className="hidden" onChange={pickFile(setIcon, setIconPreview)} />
      </div>

      {/* Name */}
      <div>
        <label className="mb-1 block text-xs font-medium text-brand-text/60">{t("hubSettings.nameLabel")}</label>
        <input {...register("name")} className="w-full rounded-xl border border-brand-lines/25 bg-brand-bgLight/40 px-3 py-2 text-sm text-brand-text focus:border-brand-accent focus:outline-none" />
      </div>

      {/* Description */}
      <div>
        <label className="mb-1 block text-xs font-medium text-brand-text/60">{t("hubSettings.descLabel")}</label>
        <textarea {...register("description")} rows={3}
          className="w-full resize-none rounded-xl border border-brand-lines/25 bg-brand-bgLight/40 px-3 py-2 text-sm text-brand-text focus:border-brand-accent focus:outline-none" />
      </div>

      {/* Visibility */}
      <label className="flex cursor-pointer items-center justify-between gap-3 rounded-xl border border-brand-lines/15 bg-brand-bgLight/30 px-4 py-3">
        <div>
          <p className="text-sm font-medium text-brand-text">{t("hubSettings.visibilityLabel")}</p>
          <p className="text-xs text-brand-text/50">{t("hubSettings.visibilityDesc")}</p>
        </div>
        <input type="checkbox" {...register("is_public")} className="h-4 w-4 accent-brand-accent" />
      </label>

      <Button type="submit" variant="primary" loading={mutation.isPending}>{t("hubSettings.saveChanges")}</Button>
    </form>
  );
}

// ---------------------------------------------------------------------------
// Moderators tab
// ---------------------------------------------------------------------------

function ModeratorsTab({ hubId }: { hubId: number }) {
  const { t } = useTranslation("social");
  const queryClient = useQueryClient();
  const [newUserId, setNewUserId] = useState("");

  const { data } = useApiSocialHubsModeratorsList({ hub: hubId } as never);
  const mods = data?.results ?? [];

  const createMod = useApiSocialHubsModeratorsCreate({
    mutation: { onSuccess: () => { setNewUserId(""); void queryClient.invalidateQueries({ queryKey: getApiSocialHubsModeratorsListQueryKey({ hub: hubId } as never) }); } },
  });
  const updateMod = useApiSocialHubsModeratorsPartialUpdate({
    mutation: { onSuccess: () => { void queryClient.invalidateQueries({ queryKey: getApiSocialHubsModeratorsListQueryKey({ hub: hubId } as never) }); } },
  });
  const deleteMod = useApiSocialHubsModeratorsDestroy({
    mutation: { onSuccess: () => { void queryClient.invalidateQueries({ queryKey: getApiSocialHubsModeratorsListQueryKey({ hub: hubId } as never) }); } },
  });

  const PERM_KEYS = ["changing_name", "changing_description", "changing_icon", "changing_banner", "managing_members", "managing_posts", "managing_chats"] as const;

  return (
    <div className="flex flex-col gap-4 py-4">
      {/* Add moderator */}
      <div className="flex gap-2">
        <input
          value={newUserId}
          onChange={(e) => setNewUserId(e.target.value)}
          placeholder={t("hubSettings.addModPlaceholder")}
          className="flex-1 rounded-xl border border-brand-lines/25 bg-brand-bgLight/40 px-3 py-2 text-sm text-brand-text focus:border-brand-accent focus:outline-none"
        />
        <Button
          size="sm"
          variant="primary"
          leftIcon={<FiPlus size={14} />}
          loading={createMod.isPending}
          onClick={() => {
            const uid = Number(newUserId);
            if (!Number.isFinite(uid)) return;
            createMod.mutate({ data: { hub: hubId, user: uid } as never });
          }}
        >
          {t("hubSettings.addMod")}
        </Button>
      </div>

      {mods.length === 0 && <EmptyState message={t("hubSettings.noModerators")} />}

      {mods.map((mod) => (
        <div key={mod.id} className="rounded-xl border border-brand-lines/15 bg-brand-bgLight/30 p-4">
          <div className="flex items-center justify-between mb-3">
            <span className="text-sm font-semibold text-brand-text">{t("hubSettings.userLabel", { id: mod.user })}</span>
            <button
              type="button"
              onClick={() => deleteMod.mutate({ id: String(mod.id) })}
              className="rounded-full p-1.5 text-red-400/70 hover:bg-red-400/10 hover:text-red-400"
            >
              <FiTrash2 size={14} />
            </button>
          </div>
          <div className="grid grid-cols-2 gap-2">
            {PERM_KEYS.map((key) => (
              <label key={key} className="flex cursor-pointer items-center gap-2 text-xs text-brand-text/70">
                <input
                  type="checkbox"
                  defaultChecked={(mod as unknown as Record<string, unknown>)[key] as boolean}
                  className="h-3.5 w-3.5 accent-brand-accent"
                  onChange={(e) => {
                    updateMod.mutate({ id: String(mod.id), data: { [key]: e.target.checked } as never });
                  }}
                />
                {t(`hubSettings.permLabels.${key}`)}
              </label>
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Tags tab
// ---------------------------------------------------------------------------

function TagsTab({ hubId }: { hubId: number }) {
  const { t } = useTranslation("social");
  const queryClient = useQueryClient();
  const [name, setName] = useState("");
  const [color, setColor] = useState("#6366f1");
  const [desc, setDesc] = useState("");

  const { data } = useApiSocialHubsTagsList({ hub: hubId } as never);
  const tags = data?.results ?? [];

  const createTag = useApiSocialHubsTagsCreate({
    mutation: {
      onSuccess: () => { setName(""); setDesc(""); void queryClient.invalidateQueries({ queryKey: getApiSocialHubsTagsListQueryKey({ hub: hubId } as never) }); },
    },
  });
  const deleteTag = useApiSocialHubsTagsDestroy({
    mutation: { onSuccess: () => { void queryClient.invalidateQueries({ queryKey: getApiSocialHubsTagsListQueryKey({ hub: hubId } as never) }); } },
  });

  return (
    <div className="flex flex-col gap-4 py-4">
      {/* Create tag form */}
      <div className="rounded-xl border border-brand-lines/15 bg-brand-bgLight/30 p-4 flex flex-col gap-3">
        <p className="text-xs font-semibold text-brand-text/60 uppercase tracking-wider">{t("hubSettings.newTag")}</p>
        <div className="flex gap-2">
          <input type="color" value={color} onChange={(e) => setColor(e.target.value)}
            className="h-9 w-9 shrink-0 cursor-pointer rounded-lg border border-brand-lines/20 bg-transparent p-0.5" />
          <input value={name} onChange={(e) => setName(e.target.value)} placeholder={t("hubSettings.tagNamePlaceholder")}
            className="flex-1 rounded-xl border border-brand-lines/25 bg-brand-bgLight/40 px-3 py-2 text-sm text-brand-text focus:border-brand-accent focus:outline-none" />
        </div>
        <input value={desc} onChange={(e) => setDesc(e.target.value)} placeholder={t("hubSettings.tagDescPlaceholder")}
          className="w-full rounded-xl border border-brand-lines/25 bg-brand-bgLight/40 px-3 py-2 text-sm text-brand-text focus:border-brand-accent focus:outline-none" />
        <Button size="sm" variant="primary" loading={createTag.isPending}
          onClick={() => name && createTag.mutate({ data: { hub: hubId, name, color, description: desc } as never })}>
          {t("hubSettings.addTag")}
        </Button>
      </div>

      {tags.length === 0 && <EmptyState message={t("hubSettings.noTags")} />}

      <div className="flex flex-wrap gap-2">
        {tags.map((tag) => (
          <div key={tag.id} className="flex items-center gap-1.5 rounded-full border px-3 py-1 text-xs font-medium"
            style={{ borderColor: tag.color + "55", color: tag.color }}>
            <span className="h-2 w-2 rounded-full" style={{ backgroundColor: tag.color }} />
            {tag.name}
            <button type="button" onClick={() => deleteTag.mutate({ id: String(tag.id) })}
              className="ml-0.5 opacity-60 hover:opacity-100">
              <FiX size={11} />
            </button>
          </div>
        ))}
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Settings page shell
// ---------------------------------------------------------------------------

export default function HubSettingsPage() {
  const { t } = useTranslation("social");
  const { name } = useParams<{ name: string }>();
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const { user } = useAuth();

  const [tab, setTab] = useState<Tab>("general");
  const { data: hub, isLoading } = useApiSocialHubsRetrieve(name!);

  const isOwner = !!(user && hub?.owner === user.id);
  const isModerator = !!(user && hub?.moderators?.some((m) => m.user === user.id));

  // Redirect if no permission
  useEffect(() => {
    if (!isLoading && hub && !isOwner && !isModerator) {
      navigate(`/social/h/${hub.name}`, { replace: true });
    }
  }, [isLoading, hub, isOwner, isModerator, navigate]);

  const destroyMutation = useApiSocialHubsDestroy({
    mutation: {
      onSuccess: () => {
        void queryClient.invalidateQueries({ queryKey: getApiSocialHubsRetrieveQueryKey(name!) });
        navigate("/social/hubs", { replace: true });
      },
    },
  });

  if (isLoading) return <div className="flex justify-center py-10"><Spinner size={28} /></div>;
  if (!hub) return <EmptyState title={t("hub.notFound")} />;

  const TABS: { key: Tab; label: string }[] = [
    { key: "general",    label: t("hubSettings.tabGeneral") },
    { key: "moderators", label: t("hubSettings.tabModerators") },
    { key: "tags",       label: t("hubSettings.tabTags") },
  ];

  return (
    <div className="mx-auto max-w-xl">
      <header className="sticky top-0 z-10 flex items-center gap-3 border-b border-brand-lines/10 bg-brand-bg/80 px-4 py-3 backdrop-blur">
        <button type="button" onClick={() => navigate(`/social/h/${hub.name}`)}
          className="rounded-full p-1 text-brand-text hover:bg-brand-lines/10">
          <FiArrowLeft size={20} />
        </button>
        <Avatar name={hub.name} src={hub.icon ?? undefined} size={28} />
        <h1 className="text-lg font-bold text-brand-text truncate">{t("hubSettings.settingsTitle", { name: hub.name })}</h1>
      </header>

      {/* Tab bar */}
      <div className="flex border-b border-brand-lines/10 px-4">
        {TABS.map(({ key, label }) => (
          <button key={key} type="button" onClick={() => setTab(key)}
            className={[
              "px-4 py-2.5 text-sm font-medium border-b-2 transition-colors",
              tab === key
                ? "border-brand-accent text-brand-accent"
                : "border-transparent text-brand-text/50 hover:text-brand-text/80",
            ].join(" ")}>
            {label}
          </button>
        ))}
      </div>

      <div className="px-4">
        {tab === "general" && <GeneralTab hubId={hub.id} hubName={hub.name} />}
        {tab === "moderators" && <ModeratorsTab hubId={hub.id} />}
        {tab === "tags" && <TagsTab hubId={hub.id} />}

        {/* Danger zone — only on general tab */}
        {isOwner && tab === "general" && (
          <div className="mt-6 mb-8 rounded-xl border border-red-400/20 bg-red-400/5 p-4">
            <p className="mb-1 text-sm font-semibold text-red-400">{t("hubSettings.dangerZone")}</p>
            <p className="mb-3 text-xs text-brand-text/50">{t("hubSettings.dangerZoneDesc")}</p>
            <Button
              variant="danger"
              size="sm"
              leftIcon={<FiTrash2 size={14} />}
              loading={destroyMutation.isPending}
              onClick={() => {
                if (confirm(t("hubSettings.confirmDelete", { name: hub.name }))) {
                  destroyMutation.mutate({ name: name! });
                }
              }}
            >
              {t("hubSettings.deleteHub")}
            </Button>
          </div>
        )}
      </div>
    </div>
  );
}
