"use client";

import { useState } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import Link from "next/link";
import { api, ChannelInput, ChannelType, NotificationChannel } from "@/lib/api";
import { Badge, Button, Card } from "@/components/ui";
import { VulnAlertRulesCard } from "@/components/vulnerabilities/VulnAlertRulesCard";

const inputClass =
  "w-full rounded-lg border border-border bg-surface-2 px-3 py-2 text-sm text-text-primary placeholder:text-text-tertiary focus:border-accent/50 focus:outline-none focus:ring-1 focus:ring-accent/30";
const labelClass = "mb-1.5 block text-sm font-medium text-text-secondary";


const CONFIG_FIELDS: Record<ChannelType, string[]> = {
  webhook: ["url"],
  slack: ["url"],
  discord: ["url"],
  telegram: ["token", "chat_id"],
  smtp: ["host", "port", "username", "password", "from", "to"],
};

function ChannelForm({ initial, onDone }: { initial?: NotificationChannel; onDone: () => void }) {
  const queryClient = useQueryClient();
  const [name, setName] = useState(initial?.name ?? "");
  const [type, setType] = useState<ChannelType>(initial?.type ?? "webhook");
  const [config, setConfig] = useState<Record<string, string>>(initial?.config ?? {});

  const { mutate: submit, isPending, error } = useMutation({
    mutationFn: (input: ChannelInput) =>
      initial ? api.updateChannel(initial.channel_id, input) : api.createChannel(input).then(() => undefined),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["channels"] });
      onDone();
    },
  });

  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        submit({ name, type, config, enabled: initial?.enabled ?? true });
      }}
      className="space-y-4"
    >
      <div>
        <label className={labelClass}>Name</label>
        <input className={inputClass} value={name} onChange={(e) => setName(e.target.value)} required />
      </div>
      <div>
        <label className={labelClass}>Type</label>
        <select
          className={inputClass}
          value={type}
          onChange={(e) => {
            setType(e.target.value as ChannelType);
            setConfig({});
          }}
        >
          {(["webhook", "smtp", "discord", "slack", "telegram"] as const).map((t) => (
            <option key={t} value={t}>
              {t}
            </option>
          ))}
        </select>
      </div>
      {CONFIG_FIELDS[type].map((field) => (
        <div key={field}>
          <label className={labelClass}>{field}</label>
          <input
            className={inputClass}
            type={field === "password" ? "password" : "text"}
            value={config[field] ?? ""}
            onChange={(e) => setConfig({ ...config, [field]: e.target.value })}
          />
        </div>
      ))}
      {error && <p className="text-sm text-danger">{(error as Error).message}</p>}
      <div className="flex gap-3">
        <Button type="submit" variant="primary" loading={isPending}>
          {initial ? "Save Changes" : "Add Channel"}
        </Button>
        <Button type="button" variant="ghost" onClick={onDone}>
          Cancel
        </Button>
      </div>
    </form>
  );
}

function ChannelRow({ ch }: { ch: NotificationChannel }) {
  const queryClient = useQueryClient();
  const [testMsg, setTestMsg] = useState<string | null>(null);
  const [editing, setEditing] = useState(false);

  const { mutate: remove } = useMutation({
    mutationFn: () => api.deleteChannel(ch.channel_id),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ["channels"] }),
  });

  const { mutate: test, isPending: testing } = useMutation({
    mutationFn: () => api.testChannel(ch.channel_id),
    onSuccess: () => setTestMsg("Sent!"),
    onError: (e) => setTestMsg((e as Error).message),
  });

  const { mutate: toggle } = useMutation({
    mutationFn: (enabled: boolean) => api.updateChannel(ch.channel_id, { enabled }),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ["channels"] }),
  });

  if (editing) {
    return (
      <div className="border-b border-border p-4 last:border-0">
        <ChannelForm initial={ch} onDone={() => setEditing(false)} />
      </div>
    );
  }

  return (
    <div className="flex items-center justify-between border-b border-border px-4 py-3 last:border-0">
      <div>
        <div className="flex items-center gap-2">
          <span className="font-medium text-text-primary">{ch.name}</span>
          <Badge variant="neutral">{ch.type}</Badge>
          {!ch.enabled && <Badge variant="warning">disabled</Badge>}
        </div>
        {testMsg && <p className="mt-1 text-xs text-text-secondary">{testMsg}</p>}
      </div>
      <div className="flex items-center gap-2">
        <Button variant="ghost" size="sm" loading={testing} onClick={() => test()}>
          Test
        </Button>
        <Button variant="ghost" size="sm" onClick={() => setEditing(true)}>
          Edit
        </Button>
        <Button variant="ghost" size="sm" onClick={() => toggle(!ch.enabled)}>
          {ch.enabled ? "Disable" : "Enable"}
        </Button>
        <Button variant="danger" size="sm" onClick={() => remove()}>
          Delete
        </Button>
      </div>
    </div>
  );
}

export default function NotificationSettingsPage() {
  const [showForm, setShowForm] = useState(false);
  const { data: channels, isLoading } = useQuery({ queryKey: ["channels"], queryFn: () => api.listChannels() });

  return (
    <div className="p-4 sm:p-6 lg:p-8">
      <div className="mb-6 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div>
          <Link href="/monitors" className="text-sm text-text-secondary hover:text-text-primary">
            ← Monitors
          </Link>
          <h1 className="mt-2 text-2xl font-bold text-text-primary">Notification Channels</h1>
          <p className="mt-1 text-sm text-text-secondary">Alert destinations for monitor state changes.</p>
        </div>
        {!showForm && (
          <Button variant="primary" onClick={() => setShowForm(true)}>
            New Channel
          </Button>
        )}
      </div>

      {showForm && (
        <Card className="mb-6 max-w-xl">
          <ChannelForm onDone={() => setShowForm(false)} />
        </Card>
      )}

      <Card padding={false}>
        {isLoading ? (
          <div className="flex justify-center py-16">
            <div className="h-8 w-8 animate-spin rounded-full border-2 border-border border-t-accent" />
          </div>
        ) : !channels || channels.length === 0 ? (
          <div className="py-16 text-center text-sm text-text-secondary">No channels configured.</div>
        ) : (
          channels.map((ch) => <ChannelRow key={ch.channel_id} ch={ch} />)
        )}
      </Card>

      {/* Beside the channels it consumes rather than on its own page: a rule is
          a routing decision about destinations configured directly above it. */}
      <div className="mt-6">
        <VulnAlertRulesCard />
      </div>
    </div>
  );
}
