'use client';

import { useState } from 'react';
import type { Position, StoreRole } from '@alqove/api-client';
import { STORE_ROLE_LABEL, STORE_ROLE_RANK } from '@alqove/api-client';
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from '@/components/ui/dialog';
import { useCreateInvitation } from '@/lib/queries/use-team';
import { apiErrorMessage } from '@/lib/api-error';

const cls = 'w-full rounded border border-forest/20 bg-white px-2 py-1.5 text-sm';

/** Roles the actor may assign: strictly below their own rank, never owner. */
export function assignableRoles(actorRank: number): StoreRole[] {
  return (Object.keys(STORE_ROLE_RANK) as StoreRole[]).filter(
    (role) => role !== 'owner' && STORE_ROLE_RANK[role] < actorRank,
  );
}

export function InviteMemberDialog({
  storeId,
  actorRank,
  positions,
  trigger,
}: {
  storeId: string;
  actorRank: number;
  positions: Position[];
  trigger: React.ReactNode;
}) {
  const [open, setOpen] = useState(false);
  const roles = assignableRoles(actorRank);
  const [email, setEmail] = useState('');
  const [role, setRole] = useState<StoreRole>(roles[roles.length - 1] ?? 'sales');
  const [positionId, setPositionId] = useState('');

  const mut = useCreateInvitation();

  const reset = () => {
    setEmail('');
    setRole(roles[roles.length - 1] ?? 'sales');
    setPositionId('');
    mut.reset();
  };

  const submit = () =>
    mut.mutate(
      {
        storeId,
        input: {
          email: email.trim(),
          role,
          default_position_id: positionId || null,
        },
      },
      {
        onSuccess: () => {
          setOpen(false);
          reset();
        },
      },
    );

  const errorMessage = apiErrorMessage(mut.error, 'Failed to send invitation.');

  return (
    <Dialog
      open={open}
      onOpenChange={(next) => {
        setOpen(next);
        if (!next) reset();
      }}
    >
      <DialogTrigger asChild>{trigger}</DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Invite a team member</DialogTitle>
        </DialogHeader>
        <div className="space-y-3">
          <Field label="Email">
            <input
              data-testid="invite-email"
              type="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              className={cls}
              placeholder="person@example.com"
            />
          </Field>
          <Field label="Role">
            <select
              data-testid="invite-role"
              value={role}
              onChange={(e) => setRole(e.target.value as StoreRole)}
              className={cls}
            >
              {roles.map((r) => (
                <option key={r} value={r}>
                  {STORE_ROLE_LABEL[r]}
                </option>
              ))}
            </select>
          </Field>
          <Field label="Default position (optional)">
            <select
              data-testid="invite-position"
              value={positionId}
              onChange={(e) => setPositionId(e.target.value)}
              className={cls}
            >
              <option value="">None</option>
              {positions.map((p) => (
                <option key={p.id} value={p.id}>
                  {p.name}
                </option>
              ))}
            </select>
          </Field>
          <p className="text-xs text-ink/60">
            They&apos;ll get an email with a link that expires in 7 days. If they don&apos;t have an
            Alqove account yet, they can create one with this email.
          </p>
          {mut.isError && (
            <p className="text-sm text-terracotta" data-testid="invite-error">
              {errorMessage}
            </p>
          )}
        </div>
        <DialogFooter>
          <button
            type="button"
            onClick={() => setOpen(false)}
            className="rounded px-3 py-1.5 text-sm text-ink/70 hover:bg-bone"
          >
            Cancel
          </button>
          <button
            type="button"
            data-testid="invite-submit"
            onClick={submit}
            disabled={mut.isPending || !email.trim() || roles.length === 0}
            className="rounded bg-forest px-3 py-1.5 text-sm font-semibold text-white hover:bg-forest/90 disabled:opacity-50"
          >
            {mut.isPending ? 'Sending…' : 'Send invitation'}
          </button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

function Field({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <label className="flex flex-col gap-1 text-sm">
      <span className="text-xs uppercase tracking-wide text-ink/60">{label}</span>
      {children}
    </label>
  );
}
