"use client";

import { useState } from "react";
import { trpc } from "~/lib/trpc/client.js";

const WEBHOOK_EVENTS = [
  "allocation.created",
  "allocation.updated",
  "allocation.deleted",
  "project.created",
  "project.status_changed",
  "vacation.approved",
  "estimate.submitted",
  "estimate.approved",
] as const;

const EVENT_LABELS: Record<string, string> = {
  "allocation.created": "Allocation Created",
  "allocation.updated": "Allocation Updated",
  "allocation.deleted": "Allocation Deleted",
  "project.created": "Project Created",
  "project.status_changed": "Project Status Changed",
  "vacation.approved": "Vacation Approved",
  "estimate.submitted": "Estimate Submitted",
  "estimate.approved": "Estimate Approved",
};

const INPUT_CLASS = "app-input";
const LABEL_CLASS = "app-label";
const PRIMARY_BUTTON =
  "rounded-xl bg-brand-600 px-4 py-2 text-sm font-semibold text-white transition hover:bg-brand-700 disabled:opacity-50";
const SECONDARY_BUTTON =
  "rounded-xl border border-gray-300 px-4 py-2 text-sm font-medium text-gray-700 transition hover:bg-gray-50 disabled:opacity-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-800";
const DANGER_BUTTON =
  "rounded-xl bg-red-600 px-4 py-2 text-sm font-semibold text-white transition hover:bg-red-700 disabled:opacity-50";

interface WebhookFormData {
  name: string;
  url: string;
  secret: string;
  events: string[];
  isActive: boolean;
}

const emptyForm: WebhookFormData = {
  name: "",
  url: "",
  secret: "",
  events: [],
  isActive: true,
};

function maskUrl(url: string): string {
  try {
    const u = new URL(url);
    const host = u.hostname;
    // Show scheme + host, mask the rest
    if (u.pathname.length > 1) {
      return `${u.protocol}//${host}/****`;
    }
    return `${u.protocol}//${host}`;
  } catch {
    return "****";
  }
}

export function WebhooksClient() {
  const utils = trpc.useUtils();
  const { data: webhooks, isLoading } = trpc.webhook.list.useQuery();
  const createMut = trpc.webhook.create.useMutation({
    onSuccess: () => {
      void utils.webhook.list.invalidate();
      setModalOpen(false);
    },
  });
  const updateMut = trpc.webhook.update.useMutation({
    onSuccess: () => {
      void utils.webhook.list.invalidate();
      setModalOpen(false);
    },
  });
  const deleteMut = trpc.webhook.delete.useMutation({
    onSuccess: () => void utils.webhook.list.invalidate(),
  });
  const testMut = trpc.webhook.test.useMutation();

  const [modalOpen, setModalOpen] = useState(false);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [form, setForm] = useState<WebhookFormData>(emptyForm);
  const [deleteConfirmId, setDeleteConfirmId] = useState<string | null>(null);
  const [testResult, setTestResult] = useState<{
    id: string;
    success: boolean;
    statusCode: number;
    statusText: string;
  } | null>(null);

  function openCreateModal() {
    setEditingId(null);
    setForm(emptyForm);
    setModalOpen(true);
  }

  function openEditModal(wh: {
    id: string;
    name: string;
    url: string;
    secret: string | null;
    events: string[];
    isActive: boolean;
  }) {
    setEditingId(wh.id);
    setForm({
      name: wh.name,
      url: wh.url,
      secret: wh.secret ?? "",
      events: wh.events,
      isActive: wh.isActive,
    });
    setModalOpen(true);
  }

  function toggleEvent(event: string) {
    setForm((prev) => ({
      ...prev,
      events: prev.events.includes(event)
        ? prev.events.filter((e) => e !== event)
        : [...prev.events, event],
    }));
  }

  function handleSubmit() {
    if (editingId) {
      updateMut.mutate({
        id: editingId,
        data: {
          name: form.name,
          url: form.url,
          ...(form.secret ? { secret: form.secret } : { secret: null }),
          events: form.events,
          isActive: form.isActive,
        },
      });
    } else {
      createMut.mutate({
        name: form.name,
        url: form.url,
        ...(form.secret ? { secret: form.secret } : {}),
        events: form.events,
        isActive: form.isActive,
      });
    }
  }

  function handleTest(id: string) {
    setTestResult(null);
    testMut.mutate(
      { id },
      {
        onSuccess: (result) => {
          setTestResult({ id, ...result });
        },
      },
    );
  }

  function handleToggleActive(id: string, currentActive: boolean) {
    updateMut.mutate({ id, data: { isActive: !currentActive } });
  }

  const isSaving = createMut.isPending || updateMut.isPending;

  return (
    <div className="mx-auto max-w-4xl space-y-6 p-6">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-gray-900 dark:text-white">Webhooks</h1>
          <p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
            Configure outbound webhooks to notify external services about events in Nexus.
          </p>
        </div>
        <button className={PRIMARY_BUTTON} onClick={openCreateModal}>
          Add Webhook
        </button>
      </div>

      {/* Webhook List */}
      {isLoading ? (
        <div className="app-surface p-8 text-center text-gray-500">Loading...</div>
      ) : !webhooks?.length ? (
        <div className="app-surface p-8 text-center text-gray-500 dark:text-gray-400">
          No webhooks configured yet.
        </div>
      ) : (
        <div className="space-y-3">
          {webhooks.map((wh) => (
            <div key={wh.id} className="app-surface flex items-center gap-4 p-4">
              {/* Active indicator */}
              <div
                className={`h-3 w-3 shrink-0 rounded-full ${
                  wh.isActive ? "bg-green-500" : "bg-gray-300 dark:bg-gray-600"
                }`}
                title={wh.isActive ? "Active" : "Inactive"}
              />

              {/* Info */}
              <div className="min-w-0 flex-1">
                <div className="flex items-center gap-2">
                  <span className="font-medium text-gray-900 dark:text-white">{wh.name}</span>
                  {wh.url.includes("hooks.slack.com") && (
                    <span className="rounded bg-purple-100 px-1.5 py-0.5 text-xs font-medium text-purple-700 dark:bg-purple-900/40 dark:text-purple-300">
                      Slack
                    </span>
                  )}
                </div>
                <div className="mt-0.5 truncate text-sm text-gray-500 dark:text-gray-400">
                  {maskUrl(wh.url)}
                </div>
                <div className="mt-1 flex flex-wrap gap-1">
                  {wh.events.map((ev) => (
                    <span
                      key={ev}
                      className="rounded bg-gray-100 px-1.5 py-0.5 text-xs text-gray-600 dark:bg-gray-800 dark:text-gray-400"
                    >
                      {EVENT_LABELS[ev] ?? ev}
                    </span>
                  ))}
                </div>
                {/* Test result */}
                {testResult && testResult.id === wh.id && (
                  <div
                    className={`mt-1 text-xs ${
                      testResult.success
                        ? "text-green-600 dark:text-green-400"
                        : "text-red-600 dark:text-red-400"
                    }`}
                  >
                    Test: {testResult.statusCode} {testResult.statusText}
                  </div>
                )}
              </div>

              {/* Actions */}
              <div className="flex shrink-0 items-center gap-2">
                <button
                  className={SECONDARY_BUTTON}
                  onClick={() => handleTest(wh.id)}
                  disabled={testMut.isPending}
                  title="Send test payload"
                >
                  Test
                </button>
                <button
                  className={SECONDARY_BUTTON}
                  onClick={() => handleToggleActive(wh.id, wh.isActive)}
                  disabled={updateMut.isPending}
                >
                  {wh.isActive ? "Disable" : "Enable"}
                </button>
                <button className={SECONDARY_BUTTON} onClick={() => openEditModal(wh)}>
                  Edit
                </button>
                {deleteConfirmId === wh.id ? (
                  <div className="flex items-center gap-1">
                    <button
                      className={DANGER_BUTTON}
                      onClick={() => {
                        deleteMut.mutate({ id: wh.id });
                        setDeleteConfirmId(null);
                      }}
                      disabled={deleteMut.isPending}
                    >
                      Confirm
                    </button>
                    <button className={SECONDARY_BUTTON} onClick={() => setDeleteConfirmId(null)}>
                      Cancel
                    </button>
                  </div>
                ) : (
                  <button className={SECONDARY_BUTTON} onClick={() => setDeleteConfirmId(wh.id)}>
                    Delete
                  </button>
                )}
              </div>
            </div>
          ))}
        </div>
      )}

      {/* Modal */}
      {modalOpen && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40">
          <div className="app-surface-strong mx-4 w-full max-w-lg space-y-5 rounded-2xl p-6 shadow-xl">
            <h2 className="text-lg font-semibold text-gray-900 dark:text-white">
              {editingId ? "Edit Webhook" : "Create Webhook"}
            </h2>

            {/* Name */}
            <div>
              <label className={LABEL_CLASS}>Name</label>
              <input
                className={INPUT_CLASS}
                value={form.name}
                onChange={(e) => setForm((prev) => ({ ...prev, name: e.target.value }))}
                placeholder="e.g. Slack Notifications"
              />
            </div>

            {/* URL */}
            <div>
              <label className={LABEL_CLASS}>URL</label>
              <input
                className={INPUT_CLASS}
                value={form.url}
                onChange={(e) => setForm((prev) => ({ ...prev, url: e.target.value }))}
                placeholder="https://hooks.slack.com/services/..."
              />
            </div>

            {/* Secret */}
            <div>
              <label className={LABEL_CLASS}>Secret (optional)</label>
              <input
                className={INPUT_CLASS}
                type="password"
                value={form.secret}
                onChange={(e) => setForm((prev) => ({ ...prev, secret: e.target.value }))}
                placeholder="HMAC signing secret"
                autoComplete="new-password"
              />
              <p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
                If set, requests include an X-Webhook-Signature header (HMAC-SHA256).
              </p>
            </div>

            {/* Events */}
            <div>
              <label className={LABEL_CLASS}>Events</label>
              <div className="mt-1 grid grid-cols-2 gap-2">
                {WEBHOOK_EVENTS.map((ev) => (
                  <label
                    key={ev}
                    className="flex items-center gap-2 rounded-lg border border-gray-200 bg-gray-50 px-3 py-2 text-sm dark:border-gray-700 dark:bg-gray-900/70"
                  >
                    <input
                      type="checkbox"
                      checked={form.events.includes(ev)}
                      onChange={() => toggleEvent(ev)}
                      className="rounded border-gray-300 text-brand-600 focus:ring-brand-500"
                    />
                    <span className="text-gray-700 dark:text-gray-300">
                      {EVENT_LABELS[ev] ?? ev}
                    </span>
                  </label>
                ))}
              </div>
            </div>

            {/* Active toggle */}
            <label className="flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300">
              <input
                type="checkbox"
                checked={form.isActive}
                onChange={(e) => setForm((prev) => ({ ...prev, isActive: e.target.checked }))}
                className="rounded border-gray-300 text-brand-600 focus:ring-brand-500"
              />
              Active
            </label>

            {/* Error display */}
            {(createMut.error || updateMut.error) && (
              <p className="text-sm text-red-600 dark:text-red-400">
                {createMut.error?.message ?? updateMut.error?.message}
              </p>
            )}

            {/* Actions */}
            <div className="flex justify-end gap-3 pt-2">
              <button
                className={SECONDARY_BUTTON}
                onClick={() => setModalOpen(false)}
                disabled={isSaving}
              >
                Cancel
              </button>
              <button
                className={PRIMARY_BUTTON}
                onClick={handleSubmit}
                disabled={isSaving || !form.name || !form.url || form.events.length === 0}
              >
                {isSaving ? "Saving..." : editingId ? "Update" : "Create"}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
