import { useState } from 'react';
import { Badge, Button, FormField, Input, Select, useToast } from '@cameleer/design-system';
import { MustacheEditor } from '../../../components/MustacheEditor/MustacheEditor';
import { useUsers, useGroups, useRoles } from '../../../api/queries/admin/rbac';
import { useOutboundConnections } from '../../../api/queries/admin/outboundConnections';
import { useSelectedEnv } from '../../../api/queries/alertMeta';
import { useRenderPreview } from '../../../api/queries/alertRules';
import { describeApiError } from '../../../api/errors';
import type { FormState } from './form-state';

type TargetKind = FormState['targets'][number]['kind'];

export function NotifyStep({
  form,
  setForm,
  ruleId,
}: {
  form: FormState;
  setForm: (f: FormState) => void;
  ruleId?: string;
}) {
  const env = useSelectedEnv();
  const { data: users } = useUsers(true);
  const { data: groups } = useGroups(true);
  const { data: roles } = useRoles(true);
  const { data: connections } = useOutboundConnections();
  const preview = useRenderPreview();
  const { toast } = useToast();
  const [lastPreview, setLastPreview] = useState<string | null>(null);

  // Filter connections to those that allow the current env.
  const availableConnections = (connections ?? []).filter(
    (c) => c.allowedEnvironmentIds.length === 0 || (!!env && c.allowedEnvironmentIds.includes(env)),
  );

  const onPreview = async () => {
    if (!ruleId) {
      toast({ title: 'Save rule first to preview', variant: 'error' });
      return;
    }
    try {
      const res = await preview.mutateAsync({ id: ruleId, req: {} });
      setLastPreview(`TITLE:\n${res.title ?? ''}\n\nMESSAGE:\n${res.message ?? ''}`);
    } catch (e) {
      toast({ title: 'Preview failed', description: describeApiError(e), variant: 'error' });
    }
  };

  const addTarget = (kind: TargetKind, targetId: string) => {
    if (!targetId) return;
    if (form.targets.some((t) => t.kind === kind && t.targetId === targetId)) return;
    setForm({ ...form, targets: [...form.targets, { kind, targetId }] });
  };
  const removeTarget = (idx: number) => {
    setForm({ ...form, targets: form.targets.filter((_, i) => i !== idx) });
  };

  const addWebhook = (outboundConnectionId: string) => {
    setForm({
      ...form,
      webhooks: [...form.webhooks, { outboundConnectionId, bodyOverride: '', headerOverrides: [] }],
    });
  };
  const removeWebhook = (idx: number) => {
    setForm({ ...form, webhooks: form.webhooks.filter((_, i) => i !== idx) });
  };
  const updateWebhook = (idx: number, patch: Partial<FormState['webhooks'][number]>) => {
    setForm({
      ...form,
      webhooks: form.webhooks.map((w, i) => (i === idx ? { ...w, ...patch } : w)),
    });
  };

  return (
    <div style={{ display: 'grid', gap: 16, maxWidth: 720 }}>
      <MustacheEditor
        label="Notification title"
        value={form.notificationTitleTmpl}
        onChange={(v) => setForm({ ...form, notificationTitleTmpl: v })}
        kind={form.conditionKind}
        singleLine
      />
      <MustacheEditor
        label="Notification message"
        value={form.notificationMessageTmpl}
        onChange={(v) => setForm({ ...form, notificationMessageTmpl: v })}
        kind={form.conditionKind}
        minHeight={120}
      />
      <div>
        <Button variant="secondary" onClick={onPreview} disabled={preview.isPending}>
          Preview rendered output
        </Button>
        {!ruleId && (
          <p style={{ marginTop: 8, fontSize: 12, color: 'var(--text-muted)' }}>
            Save the rule first to preview rendered output.
          </p>
        )}
        {lastPreview && (
          <pre
            style={{
              marginTop: 8,
              padding: 8,
              background: 'var(--code-bg)',
              borderRadius: 6,
              fontSize: 12,
              whiteSpace: 'pre-wrap',
            }}
          >
            {lastPreview}
          </pre>
        )}
      </div>

      <FormField label="Notification targets">
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 8 }}>
          {form.targets.map((t, i) => (
            <Badge
              key={`${t.kind}:${t.targetId}`}
              label={`${t.kind}: ${t.targetId}`}
              variant="outlined"
              onRemove={() => removeTarget(i)}
            />
          ))}
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          <Select
            value=""
            onChange={(e) => {
              addTarget('USER', e.target.value);
              e.target.value = '';
            }}
            options={[
              { value: '', label: '+ User' },
              ...(users ?? []).map((u) => ({ value: u.userId, label: u.displayName ?? u.userId })),
            ]}
          />
          <Select
            value=""
            onChange={(e) => {
              addTarget('GROUP', e.target.value);
              e.target.value = '';
            }}
            options={[
              { value: '', label: '+ Group' },
              ...(groups ?? []).map((g) => ({ value: g.id, label: g.name })),
            ]}
          />
          <Select
            value=""
            onChange={(e) => {
              addTarget('ROLE', e.target.value);
              e.target.value = '';
            }}
            options={[
              { value: '', label: '+ Role' },
              ...(roles ?? []).map((r) => ({ value: r.name, label: r.name })),
            ]}
          />
        </div>
      </FormField>

      <FormField label="Webhook destinations (outbound connections)">
        <Select
          value=""
          onChange={(e) => {
            if (e.target.value) addWebhook(e.target.value);
            e.target.value = '';
          }}
          options={[
            { value: '', label: '+ Add webhook' },
            ...availableConnections.map((c) => ({ value: c.id, label: c.name })),
          ]}
        />
        {form.webhooks.map((w, i) => {
          const conn = availableConnections.find((c) => c.id === w.outboundConnectionId);
          return (
            <div
              key={`${w.outboundConnectionId}-${i}`}
              style={{
                padding: 12,
                border: '1px solid var(--border)',
                borderRadius: 6,
                marginTop: 8,
                display: 'grid',
                gap: 8,
              }}
            >
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <strong>{conn?.name ?? w.outboundConnectionId}</strong>
                <Button size="sm" variant="secondary" onClick={() => removeWebhook(i)}>
                  Remove
                </Button>
              </div>
              <MustacheEditor
                label="Body override (optional)"
                value={w.bodyOverride}
                onChange={(v) => updateWebhook(i, { bodyOverride: v })}
                kind={form.conditionKind}
                placeholder="Leave empty to use connection default"
                minHeight={80}
              />
              <FormField label="Header overrides">
                {w.headerOverrides.map((h, hi) => (
                  <div key={hi} style={{ display: 'flex', gap: 8, marginBottom: 4 }}>
                    <Input
                      value={h.key}
                      placeholder="Header name"
                      onChange={(e) => {
                        const heads = [...w.headerOverrides];
                        heads[hi] = { ...heads[hi], key: e.target.value };
                        updateWebhook(i, { headerOverrides: heads });
                      }}
                    />
                    <Input
                      value={h.value}
                      placeholder="Mustache value"
                      onChange={(e) => {
                        const heads = [...w.headerOverrides];
                        heads[hi] = { ...heads[hi], value: e.target.value };
                        updateWebhook(i, { headerOverrides: heads });
                      }}
                    />
                    <Button
                      size="sm"
                      variant="secondary"
                      onClick={() =>
                        updateWebhook(i, { headerOverrides: w.headerOverrides.filter((_, x) => x !== hi) })
                      }
                    >
                      &times;
                    </Button>
                  </div>
                ))}
                <Button
                  size="sm"
                  variant="secondary"
                  onClick={() =>
                    updateWebhook(i, { headerOverrides: [...w.headerOverrides, { key: '', value: '' }] })
                  }
                >
                  + Header override
                </Button>
              </FormField>
            </div>
          );
        })}
      </FormField>
    </div>
  );
}
