"use client";

import { useEffect, useState } from "react";
import { useRouter } from "@/i18n/navigation";
import { useSession } from "next-auth/react";
import { useTranslations } from "next-intl";
import { Building2, Loader2, UserCircle } from "lucide-react";
import Button from "@/components/ui/Button";
import Modal from "@/components/ui/Modal";
import { readApiJson, toastPromise } from "@/lib/toast";

interface BusinessSummary {
  id: string;
  name: string;
  logo?: string | null;
}

interface StaffOption {
  userId: string;
  name: string;
  email: string;
  image: string | null;
  roleName: string | null;
  membershipType: "business" | "franchise" | "location";
  membershipLabel: string;
}

interface BusinessImpersonateModalProps {
  business: BusinessSummary;
  open: boolean;
  onClose: () => void;
}

export default function BusinessImpersonateModal({
  business,
  open,
  onClose,
}: BusinessImpersonateModalProps) {
  const t = useTranslations("businesses");
  const tc = useTranslations("common");
  const router = useRouter();
  const { update } = useSession();

  const [staff, setStaff] = useState<StaffOption[]>([]);
  const [loadingStaff, setLoadingStaff] = useState(false);
  const [selectedStaffId, setSelectedStaffId] = useState("");
  const [starting, setStarting] = useState(false);

  useEffect(() => {
    if (!open) return;
    setSelectedStaffId("");
    setLoadingStaff(true);
    fetch(`/api/businesses/${business.id}/impersonate-staff`)
      .then(async (res) => {
        const data = await res.json().catch(() => ({}));
        if (!res.ok) throw new Error(data.error ?? tc("somethingWrong"));
        setStaff(data.staff ?? []);
      })
      .catch(() => setStaff([]))
      .finally(() => setLoadingStaff(false));
  }, [open, business.id, tc]);

  if (!open) return null;

  async function handleStart() {
    setStarting(true);
    try {
      const payload = await toastPromise(
        readApiJson(
          await fetch("/api/businesses/impersonate", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
              businessId: business.id,
              staffUserId: selectedStaffId || null,
            }),
          }),
          tc("somethingWrong")
        ),
        {
          loading: t("startingBusinessImpersonation"),
          success: t("businessImpersonationStarted"),
        }
      );
      await update({ impersonateBusiness: payload });
      onClose();
      router.push("/dashboard/business");
      router.refresh();
    } catch {
      // toast
    } finally {
      setStarting(false);
    }
  }

  return (
    <Modal
      title={t("impersonateBusinessTitle")}
      description={t("impersonateBusinessHint", { name: business.name })}
      onClose={onClose}
    >
      <div className="space-y-5 px-5 py-5 sm:px-6">
        <div className="flex items-center gap-3 rounded-xl border border-[var(--border)] bg-[var(--bg)]/40 p-3.5">
          <div className="flex h-11 w-11 shrink-0 items-center justify-center overflow-hidden rounded-lg bg-[var(--accent)]/10 text-[var(--accent)]">
            {business.logo ? (
              // eslint-disable-next-line @next/next/no-img-element
              <img src={business.logo} alt="" className="h-full w-full object-cover" />
            ) : (
              <Building2 className="h-5 w-5" />
            )}
          </div>
          <div className="min-w-0">
            <p className="font-medium text-[var(--text)]">{business.name}</p>
            <p className="text-xs text-[var(--text-faint)]">{t("selectStaffHint")}</p>
          </div>
        </div>

        <div className="space-y-2">
          <label className="block text-sm font-medium text-[var(--text)]">{t("viewAs")}</label>
          {loadingStaff ? (
            <div className="flex items-center gap-2 rounded-lg border border-[var(--border)] px-3 py-3 text-sm text-[var(--text-muted)]">
              <Loader2 className="h-4 w-4 animate-spin" />
              {tc("loading")}
            </div>
          ) : (
            <div className="max-h-64 space-y-2 overflow-y-auto rounded-xl border border-[var(--border)] bg-[var(--bg)]/40 p-2">
              <button
                type="button"
                onClick={() => setSelectedStaffId("")}
                className={`flex w-full cursor-pointer items-center gap-3 rounded-lg border px-3 py-2.5 text-start transition-colors ${
                  selectedStaffId === ""
                    ? "border-sky-500/40 bg-sky-500/10"
                    : "border-transparent hover:bg-[var(--bg-hover)]"
                }`}
              >
                <div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-[var(--accent)]/10 text-[var(--accent)]">
                  <Building2 className="h-4 w-4" />
                </div>
                <div className="min-w-0">
                  <p className="text-sm font-medium text-[var(--text)]">{t("ownerView")}</p>
                  <p className="text-xs text-[var(--text-faint)]">{t("ownerViewHint")}</p>
                </div>
              </button>

              {staff.length === 0 ? (
                <p className="px-2 py-4 text-center text-xs text-[var(--text-muted)]">{t("noStaffToImpersonate")}</p>
              ) : (
                staff.map((member) => (
                  <button
                    key={member.userId}
                    type="button"
                    onClick={() => setSelectedStaffId(member.userId)}
                    className={`flex w-full cursor-pointer items-center gap-3 rounded-lg border px-3 py-2.5 text-start transition-colors ${
                      selectedStaffId === member.userId
                        ? "border-sky-500/40 bg-sky-500/10"
                        : "border-transparent hover:bg-[var(--bg-hover)]"
                    }`}
                  >
                    <div className="flex h-9 w-9 shrink-0 items-center justify-center overflow-hidden rounded-full bg-[var(--bg-elevated)] text-[var(--text-muted)] ring-1 ring-[var(--border)]">
                      {member.image ? (
                        // eslint-disable-next-line @next/next/no-img-element
                        <img src={member.image} alt="" className="h-full w-full object-cover" />
                      ) : (
                        <UserCircle className="h-5 w-5" />
                      )}
                    </div>
                    <div className="min-w-0">
                      <p className="truncate text-sm font-medium text-[var(--text)]">{member.name}</p>
                      <p className="truncate text-xs text-[var(--text-faint)]">
                        {member.roleName ?? t("noRole")} · {member.membershipLabel}
                      </p>
                    </div>
                  </button>
                ))
              )}
            </div>
          )}
        </div>

        <div className="flex justify-end gap-2.5 border-t border-[var(--border)] pt-4">
          <Button type="button" variant="secondary" onClick={onClose} disabled={starting}>
            {tc("cancel")}
          </Button>
          <Button type="button" onClick={handleStart} disabled={starting || loadingStaff}>
            {starting ? (
              <>
                <Loader2 className="h-4 w-4 animate-spin" />
                {tc("loading")}
              </>
            ) : (
              t("startBusinessView")
            )}
          </Button>
        </div>
      </div>
    </Modal>
  );
}
