import { useEffect, useState } from 'react';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
import {
  ArrowLeft,
  CreditCard,
  Mail,
  Shield,
  UserPlus,
  Users,
  X,
} from 'lucide-react';
import { toast } from 'sonner';
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
import { HumanAvatar } from '@/components/human-avatar';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Separator } from '@/components/ui/separator';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Muted } from '@/components/ui/typography';
import { WindowControls } from '@/components/window-controls';
import { useNetworks } from '@/hooks/use-networks';
import {
  useNetworkInvitations,
  useRevokeInvitation,
  useRemoveMember,
} from '@/hooks/use-member-management';
import { useAuthStore } from '@/stores/auth-store';
import { BillingSection } from '@/features/network-billing';
import { AddMembersDialog } from '@/features/network-settings/add-members-dialog';
import { ConfirmDestructiveOverlay } from '@/components/confirm-destructive-overlay';
import type { Human } from '@/api/types';

type Section = 'members' | 'billing';

function MemberRow({
  human,
  isAdmin,
  onRemove,
}: {
  human: Human;
  isAdmin: boolean;
  onRemove?: () => void;
}) {
  const initials = human.email_prefix.slice(0, 2).toUpperCase();

  return (
    <div className="flex w-full items-center gap-3 px-4 py-3">
      <HumanAvatar
        avatarObjectId={human.avatar_object_id}
        initials={initials}
        fallbackClassName="bg-primary/10 text-primary font-medium"
      />
      <div className="min-w-0 flex-1">
        <p className="truncate text-sm font-medium">{human.email_prefix}</p>
        <Muted className="text-xs">{human.email}</Muted>
      </div>
      {isAdmin && (
        <Badge variant="secondary" className="shrink-0">
          <Shield className="mr-1 size-3" />
          Admin
        </Badge>
      )}
      {onRemove && (
        <Button
          variant="ghost"
          size="icon-sm"
          onClick={onRemove}
          className="text-muted-foreground hover:text-destructive shrink-0"
          aria-label={`Remove ${human.email}`}
        >
          <X className="size-3.5" />
        </Button>
      )}
    </div>
  );
}

function PendingInvitationRow({
  email,
  networkId,
}: {
  email: string;
  networkId: string;
}) {
  const revokeInvitation = useRevokeInvitation(networkId);

  const handleRevoke = () => {
    revokeInvitation.mutate(email, {
      onSuccess: () => {
        toast.success(`Invitation to ${email} revoked`);
      },
    });
  };

  return (
    <div className="flex w-full items-center gap-3 px-4 py-3">
      <span className="text-muted-foreground flex size-8 items-center justify-center">
        <Mail className="size-4" />
      </span>
      <div className="min-w-0 flex-1">
        <p className="truncate text-sm">{email}</p>
        <Muted className="text-xs">Pending</Muted>
      </div>
      <Button
        variant="ghost"
        size="icon-sm"
        onClick={handleRevoke}
        disabled={revokeInvitation.isPending}
        className="text-muted-foreground hover:text-destructive shrink-0"
      >
        <X className="size-3.5" />
      </Button>
    </div>
  );
}

function SectionHeading({
  title,
  description,
  count,
  action,
}: {
  title: string;
  description?: string;
  count?: number;
  action?: React.ReactNode;
}) {
  return (
    <div className="mb-3 flex items-start justify-between gap-3">
      <div className="min-w-0">
        <div className="flex items-center gap-2">
          <h2 className="text-base font-semibold tracking-tight">{title}</h2>
          {count != null && (
            <Badge variant="secondary" className="tabular-nums">
              {count}
            </Badge>
          )}
        </div>
        {description && <Muted className="mt-0.5 text-xs">{description}</Muted>}
      </div>
      {action}
    </div>
  );
}

function Panel({ children }: { children: React.ReactNode }) {
  return (
    <section className="bg-card/40 overflow-hidden rounded-lg border">
      {children}
    </section>
  );
}

export default function NetworkSettingsPage() {
  const navigate = useNavigate();
  const { networkId } = useParams<{ networkId: string }>();
  if (!networkId)
    throw new Error('NetworkSettingsPage requires a :networkId route param');
  const [searchParams, setSearchParams] = useSearchParams();
  const { data: networks } = useNetworks();
  const network = networks?.find((n) => n.id === networkId);
  const { data: invitations, error: invitationsError } =
    useNetworkInvitations(networkId);
  const currentUser = useAuthStore((s) => s.user);
  const isAdmin = currentUser?.id === network?.admin_human.id;
  const [memberToRemove, setMemberToRemove] = useState<Human | null>(null);
  // Onboarding: opening settings with `?add=1` (e.g. right after creating a
  // network) starts with the Add members dialog open. Non-admins never render
  // the dialog, so the initial value is harmless for them.
  const [addOpen, setAddOpen] = useState(() => searchParams.get('add') === '1');
  const removeMember = useRemoveMember(networkId);

  const section: Section =
    searchParams.get('section') === 'billing' ? 'billing' : 'members';

  const setSection = (value: string) => {
    const next = new URLSearchParams(searchParams);
    if (value === 'billing') next.set('section', value);
    else next.delete('section');
    setSearchParams(next, { replace: true });
  };

  // Strip the one-shot `add` param so the dialog doesn't reopen on refresh or
  // back navigation. The initial open state was already captured above.
  useEffect(() => {
    if (searchParams.get('add') !== '1') return;
    setSearchParams(
      (prev) => {
        const next = new URLSearchParams(prev);
        next.delete('add');
        return next;
      },
      { replace: true },
    );
  }, [setSearchParams, searchParams]);

  const networkName = network?.name ?? 'Network';
  const memberCount = network?.humans.length ?? 0;
  const pendingCount = invitations?.length ?? 0;
  const networkInitials = networkName.slice(0, 2).toUpperCase();

  return (
    <div className="flex h-screen flex-col">
      <div className="drag-region flex items-center gap-3 border-b px-3 py-1">
        <WindowControls />
        <Button
          variant="ghost"
          size="sm"
          className="no-drag text-muted-foreground"
          onClick={() => navigate(`/${networkId}`)}
        >
          <ArrowLeft className="size-3.5" />
        </Button>
        <span className="text-sm font-medium">Settings</span>
        <div className="flex-1" />
      </div>

      <Tabs
        value={section}
        onValueChange={setSection}
        orientation="vertical"
        className="min-h-0 flex-1 gap-0"
      >
        <aside className="flex w-52 shrink-0 flex-col gap-4 border-r p-3">
          <div className="flex items-center gap-3 px-1 pt-1">
            <Avatar>
              <AvatarFallback className="bg-primary/10 text-primary font-medium">
                {networkInitials}
              </AvatarFallback>
            </Avatar>
            <div className="min-w-0 flex-1">
              <p className="truncate text-sm font-semibold">{networkName}</p>
              <Muted className="text-xs">
                {memberCount} {memberCount === 1 ? 'member' : 'members'}
              </Muted>
            </div>
          </div>
          <TabsList variant="line" className="w-full gap-1">
            <TabsTrigger value="members">
              <Users />
              Members
            </TabsTrigger>
            <TabsTrigger value="billing">
              <CreditCard />
              Plan & Billing
            </TabsTrigger>
          </TabsList>
        </aside>

        <ScrollArea className="min-h-0 flex-1">
          <TabsContent value="members" className="p-4">
            <SectionHeading
              title="Members"
              description="People with access to this network."
              count={memberCount}
              action={
                isAdmin ? (
                  <Button
                    size="sm"
                    className="shrink-0"
                    onClick={() => setAddOpen(true)}
                  >
                    <UserPlus className="mr-1 size-3.5" />
                    Add members
                  </Button>
                ) : undefined
              }
            />
            <Panel>
              {network?.humans.map((human, index) => {
                const isRowAdmin = human.id === network.admin_human.id;
                const canRemove =
                  isAdmin && !isRowAdmin && human.id !== currentUser?.id;
                return (
                  <div key={human.id}>
                    <MemberRow
                      human={human}
                      isAdmin={isRowAdmin}
                      onRemove={
                        canRemove ? () => setMemberToRemove(human) : undefined
                      }
                    />
                    {index < network.humans.length - 1 && (
                      <Separator className="mx-4" />
                    )}
                  </div>
                );
              })}
            </Panel>

            {isAdmin && (
              <div className="mt-6">
                <SectionHeading
                  title="Pending invitations"
                  description="Invites that haven't been accepted yet."
                  count={pendingCount > 0 ? pendingCount : undefined}
                />
                {invitationsError ? (
                  <Panel>
                    <p className="text-muted-foreground px-4 py-3 text-xs">
                      Couldn't load pending invitations.
                    </p>
                  </Panel>
                ) : invitations && invitations.length > 0 ? (
                  <Panel>
                    {invitations.map((inv, index) => (
                      <div key={inv.email}>
                        <PendingInvitationRow
                          email={inv.email}
                          networkId={networkId}
                        />
                        {index < invitations.length - 1 && (
                          <Separator className="mx-4" />
                        )}
                      </div>
                    ))}
                  </Panel>
                ) : (
                  <Muted className="text-xs">No pending invitations.</Muted>
                )}
              </div>
            )}
          </TabsContent>

          <TabsContent value="billing" className="p-4">
            <SectionHeading
              title="Plan & Billing"
              description={
                isAdmin
                  ? 'Manage your plan, seats, and payment.'
                  : "Your network's current plan and usage."
              }
            />
            <Panel>
              <BillingSection networkId={networkId} />
            </Panel>
          </TabsContent>
        </ScrollArea>
      </Tabs>

      {isAdmin && (
        <AddMembersDialog
          networkId={networkId}
          open={addOpen}
          onOpenChange={setAddOpen}
        />
      )}

      {memberToRemove && (
        <ConfirmDestructiveOverlay
          title={`Remove ${memberToRemove.email_prefix}?`}
          description={
            <ul className="list-disc space-y-1 pl-4">
              <li>
                They'll lose access to this network's streams and files within
                seconds.
              </li>
              <li>Any content they posted stays in the network.</li>
              <li>
                If they're in a live huddle, they may remain until the call
                ends.
              </li>
            </ul>
          }
          confirmLabel="Remove"
          pendingLabel="Removing…"
          isPending={removeMember.isPending}
          onConfirm={() => {
            const target = memberToRemove;
            removeMember.mutate(target.id, {
              onSuccess: () => {
                toast.success(`Removed ${target.email}`);
                setMemberToRemove(null);
              },
            });
          }}
          onClose={() => {
            if (!removeMember.isPending) setMemberToRemove(null);
          }}
        />
      )}
    </div>
  );
}
