/**
 * Detail view for a single tenant. URL: /companies/{id}.
 *
 * Layout:
 *   - Header: name + status badge + back link
 *   - Edit form (display_name, contact_email, rate_limit, fcm_shared)
 *     — fields are disabled for tenant_admin except display_name + contact_email
 *   - Status actions: Suspend / Activate / Archive (super_admin only)
 *   - Metadata panel: created, updated, archived_at
 *
 * The archive action requires a typed confirmation dialog.
 */

import { useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { useNavigate, useParams } from 'react-router-dom';
import { ArrowLeft, AlertTriangle } from 'lucide-react';
import { toast } from 'sonner';

import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
  DialogClose,
} from '@/components/ui/dialog';

import { useAuth } from '@/lib/auth-context';
import { canViewCompanies, isSuperAdmin } from "@/lib/scope";
import {
  getErrorMessage,
  useSetTenantStatus,
  useTenant,
  useUpdateTenant,
} from './api';
import { StatusBadge, formatDate, formatRateLimit } from './format';

const formSchema = z.object({
  display_name: z.string().min(1, 'Display name is required'),
  contact_email: z.string().email('Enter a valid email'),
  rate_limit_per_sec: z
    .number({ invalid_type_error: 'Enter a number' })
    .int('Whole number only')
    .min(1)
    .max(1_000_000),
  fcm_shared: z.boolean(),
});

type FormValues = z.infer<typeof formSchema>;

const EMPTY_DEFAULTS: FormValues = {
  display_name: '',
  contact_email: '',
  rate_limit_per_sec: 10000,
  fcm_shared: true,
};

export function CompanyDetailPage() {
  const { id = '' } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const { user } = useAuth();
  const canEditAll = isSuperAdmin(user?.role);
  const canView = canViewCompanies(user?.role);

  const tenantQ = useTenant(id);
  const update = useUpdateTenant(id);
  const setStatus = useSetTenantStatus(id);

  const form = useForm<FormValues>({
    resolver: zodResolver(formSchema),
    defaultValues: EMPTY_DEFAULTS,
  });

  // Reset the form whenever the loaded tenant changes. This way
  // navigating between detail pages doesn't show stale values.
  // We use setValue (not reset) so the zodResolver doesn't
  // re-run; the server has already validated these values.
  useEffect(() => {
    const t = tenantQ.data;
    if (!t) return;
    form.setValue('display_name', t.display_name);
    form.setValue('contact_email', t.contact_email);
    form.setValue('rate_limit_per_sec', t.rate_limit_per_sec);
    form.setValue('fcm_shared', t.fcm_shared);
  }, [tenantQ.data, form]);

  if (!canView) {
    return (
      <div className="rounded-md border bg-card p-6 text-sm text-muted-foreground">
        You do not have access to this company.
      </div>
    );
  }

  if (tenantQ.isError) {
    const msg = getErrorMessage(tenantQ.error);
    return (
      <div className="space-y-3">
        <Button variant="ghost" size="sm" onClick={() => navigate('/companies')}>
          <ArrowLeft className="h-4 w-4" />
          Back
        </Button>
        <div className="rounded-md border border-destructive/40 bg-destructive/5 p-4 text-sm text-destructive">
          {msg}
        </div>
      </div>
    );
  }

  if (!tenantQ.data) {
    return <div className="text-sm text-muted-foreground">Loading…</div>;
  }

  const t = tenantQ.data;

  const onSubmit = form.handleSubmit(async (values) => {
    try {
      await update.mutateAsync({
        display_name: values.display_name.trim(),
        contact_email: values.contact_email.trim(),
        rate_limit_per_sec: values.rate_limit_per_sec,
        fcm_shared: values.fcm_shared,
      });
      toast.success('Saved');
    } catch (err) {
      toast.error(getErrorMessage(err));
    }
  });

  const onChangeStatus = async (next: 'active' | 'suspended' | 'archived') => {
    try {
      await setStatus.mutateAsync(next);
      toast.success(`Status set to ${next}`);
    } catch (err) {
      toast.error(getErrorMessage(err));
    }
  };

  return (
    <div className="flex flex-col gap-6">
      <div className="flex flex-col gap-2">
        <Button
          variant="ghost"
          size="sm"
          className="self-start"
          onClick={() => navigate('/companies')}
        >
          <ArrowLeft className="h-4 w-4" />
          Back to companies
        </Button>
        <div className="flex items-center gap-3">
          <h1 className="text-2xl font-semibold tracking-tight">{t.display_name}</h1>
          <StatusBadge status={t.status} />
        </div>
        <p className="text-sm text-muted-foreground">
          <code className="rounded bg-muted px-1.5 py-0.5 text-xs">{t.slug}</code>
          <span className="mx-2 opacity-50">·</span>
          created {formatDate(t.created_at)}
        </p>
      </div>

      <div className="grid gap-6 md:grid-cols-3">
        <Card className="md:col-span-2">
          <CardHeader>
            <CardTitle>Details</CardTitle>
            <CardDescription>
              {canEditAll
                ? 'All fields are editable.'
                : 'Display name and contact email are editable. Other fields require a super-admin.'}
            </CardDescription>
          </CardHeader>
          <CardContent>
            <form onSubmit={onSubmit} className="space-y-4">
              <div className="space-y-2">
                <Label htmlFor="display_name">Display name</Label>
                <Input
                  id="display_name"
                  {...form.register('display_name')}
                  aria-invalid={Boolean(form.formState.errors.display_name)}
                />
                {form.formState.errors.display_name ? (
                  <p className="text-xs text-destructive">
                    {form.formState.errors.display_name.message}
                  </p>
                ) : null}
              </div>

              <div className="space-y-2">
                <Label htmlFor="contact_email">Contact email</Label>
                <Input
                  id="contact_email"
                  type="email"
                  autoComplete="off"
                  {...form.register('contact_email')}
                  aria-invalid={Boolean(form.formState.errors.contact_email)}
                />
                {form.formState.errors.contact_email ? (
                  <p className="text-xs text-destructive">
                    {form.formState.errors.contact_email.message}
                  </p>
                ) : null}
              </div>

              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-2">
                  <Label htmlFor="rate_limit_per_sec">Rate limit</Label>
                  <Input
                    id="rate_limit_per_sec"
                    type="number"
                    min={1}
                    max={1_000_000}
                    disabled={!canEditAll}
                    {...form.register('rate_limit_per_sec', { valueAsNumber: true })}
                    aria-invalid={Boolean(form.formState.errors.rate_limit_per_sec)}
                  />
                  {form.formState.errors.rate_limit_per_sec ? (
                    <p className="text-xs text-destructive">
                      {form.formState.errors.rate_limit_per_sec.message}
                    </p>
                  ) : null}
                </div>
                <div className="space-y-2">
                  <Label>FCM pool</Label>
                  <label className="flex items-center gap-2 rounded-md border bg-muted/40 p-2 text-sm">
                    <input
                      type="checkbox"
                      className="h-4 w-4 rounded border-input"
                      disabled={!canEditAll}
                      {...form.register('fcm_shared')}
                    />
                    Use shared FCM pool
                  </label>
                </div>
              </div>

              <div className="flex justify-end">
                <Button type="submit" disabled={update.isPending}>
                  {update.isPending ? 'Saving…' : 'Save changes'}
                </Button>
              </div>
            </form>
          </CardContent>
        </Card>

        <div className="space-y-4">
          {canEditAll ? (
            <Card>
              <CardHeader>
                <CardTitle>Status</CardTitle>
                <CardDescription>
                  Suspending stops new ingest immediately. Archiving is
                  permanent and is only used to retire a tenant.
                </CardDescription>
              </CardHeader>
              <CardContent className="space-y-2">
                {t.status === 'active' ? (
                  <Button
                    variant="outline"
                    className="w-full"
                    disabled={setStatus.isPending}
                    onClick={() => void onChangeStatus('suspended')}
                  >
                    Suspend
                  </Button>
                ) : t.status === 'suspended' ? (
                  <Button
                    variant="default"
                    className="w-full"
                    disabled={setStatus.isPending}
                    onClick={() => void onChangeStatus('active')}
                  >
                    Activate
                  </Button>
                ) : null}
                {t.status !== 'archived' ? (
                  <ArchiveButton
                    onConfirm={() => void onChangeStatus('archived')}
                    pending={setStatus.isPending}
                  />
                ) : (
                  <p className="rounded-md border bg-muted/40 p-3 text-xs text-muted-foreground">
                    Archived. Status changes are not allowed.
                  </p>
                )}
              </CardContent>
            </Card>
          ) : null}

          <Card>
            <CardHeader>
              <CardTitle className="text-base">Metadata</CardTitle>
            </CardHeader>
            <CardContent className="space-y-2 text-sm">
              <Row label="ID" value={<code className="text-xs">{t.id}</code>} />
              <Row label="Slug" value={<code className="text-xs">{t.slug}</code>} />
              <Row label="Rate limit" value={formatRateLimit(t.rate_limit_per_sec)} />
              <Row label="FCM" value={t.fcm_shared ? 'shared' : 'dedicated'} />
              <Row label="Created" value={formatDate(t.created_at)} />
              <Row label="Updated" value={formatDate(t.updated_at)} />
              {t.archived_at ? (
                <Row label="Archived" value={formatDate(t.archived_at)} />
              ) : null}
            </CardContent>
          </Card>
        </div>
      </div>
    </div>
  );
}

function Row({ label, value }: { label: string; value: React.ReactNode }) {
  return (
    <div className="flex items-center justify-between gap-2">
      <span className="text-xs uppercase tracking-wider text-muted-foreground">{label}</span>
      <span className="text-right">{value}</span>
    </div>
  );
}

function ArchiveButton({
  onConfirm,
  pending,
}: {
  onConfirm: () => void;
  pending: boolean;
}) {
  return (
    <Dialog>
      <DialogTrigger asChild>
        <Button variant="destructive" className="w-full" disabled={pending}>
          Archive…
        </Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <AlertTriangle className="h-4 w-4 text-destructive" />
            Archive this company?
          </DialogTitle>
          <DialogDescription>
            Archiving is <strong>permanent</strong>: the tenant cannot
            be reactivated, and new events will be rejected. Existing
            rows (deliveries, audit, DLQ) are kept for compliance but
            are not surfaced in the UI.
          </DialogDescription>
        </DialogHeader>
        <DialogFooter>
          <DialogClose asChild>
            <Button variant="ghost" disabled={pending}>
              Cancel
            </Button>
          </DialogClose>
          <Button variant="destructive" disabled={pending} onClick={onConfirm}>
            {pending ? 'Archiving…' : 'Archive company'}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
