"use client";

import { useMemo, useState } from "react";
import {
  Code2,
  Copy,
  KeyRound,
  Link2,
  RefreshCcw,
  Shield,
  Webhook,
} from "lucide-react";
import { useTeams } from "@/hooks/use-teams";
import { useDeveloperPortal } from "@/hooks/use-developer-portal";
import { DEVELOPER_ACCESS_LEVEL_OPTIONS, WEBHOOK_EVENT_OPTIONS } from "@/lib/developers/catalog";
import type { DeveloperAccessLevel, WebhookEventType } from "@/types";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { EmptyState } from "@/components/ui/empty-state";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select } from "@/components/ui/select";
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";

function formatDate(value: string | null) {
  if (!value) return "Never";
  return new Intl.DateTimeFormat(undefined, {
    dateStyle: "medium",
    timeStyle: "short",
  }).format(new Date(value));
}

export default function DevelopersPage() {
  const { activeTeam } = useTeams();
  const {
    activeTeamId,
    tokens,
    webhooks,
    deliveriesByWebhook,
    loading,
    createToken,
    revokeToken,
    createWebhook,
    updateWebhook,
    deleteWebhook,
    fetchDeliveries,
    sendTestWebhook,
    refetch,
  } = useDeveloperPortal();

  const [tokenName, setTokenName] = useState("");
  const [accessLevel, setAccessLevel] = useState<DeveloperAccessLevel>("read_write");
  const [expiresAt, setExpiresAt] = useState("");
  const [webhookName, setWebhookName] = useState("");
  const [webhookUrl, setWebhookUrl] = useState("");
  const [selectedEvents, setSelectedEvents] = useState<WebhookEventType[]>([
    "project.created",
    "task.created",
    "task.updated",
  ]);
  const [latestSecret, setLatestSecret] = useState<string | null>(null);
  const [latestToken, setLatestToken] = useState<string | null>(null);
  const [submittingToken, setSubmittingToken] = useState(false);
  const [submittingWebhook, setSubmittingWebhook] = useState(false);
  const [feedback, setFeedback] = useState<string | null>(null);
  const workspaceLabel = activeTeamId ? activeTeam?.name || "Team workspace" : "Personal workspace";
  const apiBase =
    process.env.NEXT_PUBLIC_APP_URL ||
    (typeof window !== "undefined" ? window.location.origin : "");
  const exampleToken = latestToken || "mb_your_token_here";

  const enabledTokenCount = useMemo(
    () => tokens.filter((token) => !token.revoked_at).length,
    [tokens]
  );

  const activeWebhookCount = useMemo(
    () => webhooks.filter((webhook) => webhook.is_active).length,
    [webhooks]
  );

  function toggleEvent(value: WebhookEventType) {
    setSelectedEvents((prev) =>
      prev.includes(value) ? prev.filter((event) => event !== value) : [...prev, value]
    );
  }

  async function handleCreateToken() {
    setSubmittingToken(true);
    setFeedback(null);

    try {
      const result = await createToken({
        name: tokenName || `${workspaceLabel} token`,
        accessLevel,
        expiresAt: expiresAt || null,
      });

      setLatestToken(result.tokenValue);
      setTokenName("");
      setExpiresAt("");
      setFeedback("API token created. Copy it now because it will not be shown again.");
    } catch (error) {
      setFeedback(error instanceof Error ? error.message : "API token could not be created.");
    } finally {
      setSubmittingToken(false);
    }
  }

  async function handleCreateWebhook() {
    setSubmittingWebhook(true);
    setFeedback(null);

    try {
      const result = await createWebhook({
        name: webhookName || `${workspaceLabel} webhook`,
        url: webhookUrl,
        eventTypes: selectedEvents,
      });

      setLatestSecret(result.signingSecret);
      setWebhookName("");
      setWebhookUrl("");
      setFeedback("Webhook created. Copy the signing secret now because it will not be shown again.");
    } catch (error) {
      setFeedback(error instanceof Error ? error.message : "Webhook could not be created.");
    } finally {
      setSubmittingWebhook(false);
    }
  }

  async function copyText(value: string) {
    try {
      await navigator.clipboard.writeText(value);
      setFeedback("Copied to clipboard.");
    } catch {
      setFeedback("Could not copy to clipboard.");
    }
  }

  async function handleRevokeToken(id: string) {
    try {
      await revokeToken(id);
      setFeedback("API token revoked.");
    } catch (error) {
      setFeedback(error instanceof Error ? error.message : "API token could not be revoked.");
    }
  }

  async function handleToggleWebhook(id: string, isActive: boolean) {
    try {
      await updateWebhook(id, { isActive: !isActive });
      setFeedback(isActive ? "Webhook paused." : "Webhook resumed.");
    } catch (error) {
      setFeedback(error instanceof Error ? error.message : "Webhook could not be updated.");
    }
  }

  async function handleLoadDeliveries(id: string) {
    try {
      await fetchDeliveries(id);
      setFeedback("Webhook deliveries loaded.");
    } catch (error) {
      setFeedback(error instanceof Error ? error.message : "Deliveries could not be loaded.");
    }
  }

  async function handleDeleteWebhook(id: string) {
    try {
      await deleteWebhook(id);
      setFeedback("Webhook deleted.");
    } catch (error) {
      setFeedback(error instanceof Error ? error.message : "Webhook could not be deleted.");
    }
  }

  async function handleSendTestWebhook(id: string, eventType?: WebhookEventType) {
    try {
      const result = await sendTestWebhook(id, eventType);
      setFeedback(`Test webhook sent for ${result.eventType}.`);
    } catch (error) {
      setFeedback(error instanceof Error ? error.message : "Test webhook could not be sent.");
    }
  }

  return (
    <div className="space-y-6">
      <div className="flex flex-wrap items-start justify-between gap-4">
        <div className="space-y-1">
          <div className="flex items-center gap-3">
            <Code2 className="h-5 w-5 text-muted-foreground" />
            <h1 className="text-2xl font-bold tracking-tight">Developers</h1>
          </div>
          <p className="text-sm text-muted-foreground">
            API tokens, webhooks, and delivery logs for <span className="font-medium">{workspaceLabel}</span>.
          </p>
        </div>

        <div className="flex items-center gap-2">
          <Badge variant="outline">{workspaceLabel}</Badge>
          <Button variant="outline" size="sm" onClick={() => void refetch()}>
            <RefreshCcw className="h-4 w-4" />
            Refresh
          </Button>
        </div>
      </div>

      {feedback && (
        <div className="rounded-xl border border-border/60 bg-muted/40 px-4 py-3 text-sm">
          {feedback}
        </div>
      )}

      {latestToken && (
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <KeyRound className="h-4 w-4" />
              New API token
            </CardTitle>
            <CardDescription>Copy this token now. It will not be shown again.</CardDescription>
          </CardHeader>
          <CardContent className="space-y-3">
            <pre className="overflow-x-auto rounded-xl border border-border/60 bg-background p-4 text-xs">{latestToken}</pre>
            <Button variant="outline" size="sm" onClick={() => void copyText(latestToken)}>
              <Copy className="h-4 w-4" />
              Copy token
            </Button>
          </CardContent>
        </Card>
      )}

      {latestSecret && (
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Shield className="h-4 w-4" />
              New webhook secret
            </CardTitle>
            <CardDescription>Copy this signing secret now. It will not be shown again.</CardDescription>
          </CardHeader>
          <CardContent className="space-y-3">
            <pre className="overflow-x-auto rounded-xl border border-border/60 bg-background p-4 text-xs">{latestSecret}</pre>
            <Button variant="outline" size="sm" onClick={() => void copyText(latestSecret)}>
              <Copy className="h-4 w-4" />
              Copy secret
            </Button>
          </CardContent>
        </Card>
      )}

      <div className="grid gap-4 md:grid-cols-3">
        <Card>
          <CardHeader className="pb-2">
            <CardDescription>Active API tokens</CardDescription>
            <CardTitle className="text-2xl">{loading ? "..." : enabledTokenCount}</CardTitle>
          </CardHeader>
        </Card>
        <Card>
          <CardHeader className="pb-2">
            <CardDescription>Active webhooks</CardDescription>
            <CardTitle className="text-2xl">{loading ? "..." : activeWebhookCount}</CardTitle>
          </CardHeader>
        </Card>
        <Card>
          <CardHeader className="pb-2">
            <CardDescription>API base</CardDescription>
            <CardTitle className="text-sm font-mono">/api/v1</CardTitle>
          </CardHeader>
        </Card>
      </div>

      <div className="grid gap-6 xl:grid-cols-[0.95fr_1.05fr]">
        <div className="space-y-6">
          <Card>
            <CardHeader>
              <CardTitle>Create API token</CardTitle>
              <CardDescription>
                Tokens are scoped to the current workspace and can be used as bearer tokens.
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-4">
              <div className="space-y-2">
                <Label htmlFor="token-name">Name</Label>
                <Input
                  id="token-name"
                  value={tokenName}
                  onChange={(event) => setTokenName(event.target.value)}
                  placeholder={`${workspaceLabel} integration`}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="access-level">Access level</Label>
                <Select
                  id="access-level"
                  value={accessLevel}
                  onChange={(event) => setAccessLevel(event.target.value as DeveloperAccessLevel)}
                >
                  {DEVELOPER_ACCESS_LEVEL_OPTIONS.map((option) => (
                    <option key={option.value} value={option.value}>
                      {option.label}
                    </option>
                  ))}
                </Select>
                <p className="text-xs text-muted-foreground">
                  {
                    DEVELOPER_ACCESS_LEVEL_OPTIONS.find((option) => option.value === accessLevel)
                      ?.description
                  }
                </p>
              </div>
              <div className="space-y-2">
                <Label htmlFor="expires-at">Expires at</Label>
                <Input
                  id="expires-at"
                  type="datetime-local"
                  value={expiresAt}
                  onChange={(event) => setExpiresAt(event.target.value)}
                />
              </div>
              <Button onClick={() => void handleCreateToken()} disabled={submittingToken}>
                <KeyRound className="h-4 w-4" />
                {submittingToken ? "Creating..." : "Create token"}
              </Button>
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>Create webhook</CardTitle>
              <CardDescription>
                Mindavio signs every payload with an HMAC signature so your receiver can verify it.
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-4">
              <div className="space-y-2">
                <Label htmlFor="webhook-name">Name</Label>
                <Input
                  id="webhook-name"
                  value={webhookName}
                  onChange={(event) => setWebhookName(event.target.value)}
                  placeholder={`${workspaceLabel} automation`}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="webhook-url">Destination URL</Label>
                <Input
                  id="webhook-url"
                  value={webhookUrl}
                  onChange={(event) => setWebhookUrl(event.target.value)}
                  placeholder="https://example.com/mindavio/webhooks"
                />
              </div>
              <div className="space-y-2">
                <Label>Events</Label>
                <div className="flex flex-wrap gap-2">
                  {WEBHOOK_EVENT_OPTIONS.map((option) => {
                    const active = selectedEvents.includes(option.value);
                    return (
                      <button
                        key={option.value}
                        type="button"
                        onClick={() => toggleEvent(option.value)}
                        className={cn(
                          "inline-flex items-center rounded-full border px-3 py-1 text-xs font-medium transition-colors",
                          active
                            ? "border-primary bg-primary/10 text-primary"
                            : "border-border bg-background text-muted-foreground hover:bg-accent"
                        )}
                      >
                        {option.label}
                      </button>
                    );
                  })}
                </div>
              </div>
              <Button
                onClick={() => void handleCreateWebhook()}
                disabled={submittingWebhook || selectedEvents.length === 0}
              >
                <Webhook className="h-4 w-4" />
                {submittingWebhook ? "Creating..." : "Create webhook"}
              </Button>
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>Quick start</CardTitle>
              <CardDescription>Copy-paste ready examples for the current developer surface.</CardDescription>
            </CardHeader>
            <CardContent className="space-y-4 text-sm">
              <div className="rounded-xl border border-border/60 bg-background p-4">
                <p className="font-medium">Available endpoints</p>
                <pre className="mt-2 overflow-x-auto text-xs">
{`GET /api/v1/projects
GET /api/v1/tasks
GET /api/v1/notes
POST /api/v1/projects
POST /api/v1/tasks
POST /api/v1/notes`}
                </pre>
              </div>
              <div className="rounded-xl border border-border/60 bg-background p-4">
                <p className="font-medium">List tasks</p>
                <pre className="mt-2 overflow-x-auto text-xs">
{`curl -H "Authorization: Bearer ${exampleToken}" \\
  ${apiBase}/api/v1/tasks?status=todo`}
                </pre>
              </div>
              <div className="rounded-xl border border-border/60 bg-background p-4">
                <p className="font-medium">Create project</p>
                <pre className="mt-2 overflow-x-auto text-xs">
{`curl -X POST ${apiBase}/api/v1/projects \\
  -H "Authorization: Bearer ${exampleToken}" \\
  -H "Content-Type: application/json" \\
  -d '{"name":"API Project","description":"Created from curl"}'`}
                </pre>
              </div>
              <div className="rounded-xl border border-border/60 bg-background p-4">
                <p className="font-medium">Webhook verification</p>
                <p className="mt-2 text-muted-foreground">
                  Every request includes `X-Mindavio-Event`, `X-Mindavio-Delivery`,
                  `X-Mindavio-Timestamp`, and `X-Mindavio-Signature`.
                </p>
                <p className="mt-2 text-muted-foreground">
                  Verify signatures with `sha256(secret, timestamp + &quot;.&quot; + rawBody)`.
                </p>
              </div>
            </CardContent>
          </Card>
        </div>

        <div className="space-y-6">
          <Card>
            <CardHeader>
              <CardTitle>API tokens</CardTitle>
              <CardDescription>Revoke old tokens when an integration is no longer trusted.</CardDescription>
            </CardHeader>
            <CardContent className="space-y-4">
              {tokens.length === 0 ? (
                <EmptyState
                  icon={<KeyRound className="h-8 w-8" />}
                  title="No tokens yet"
                  description="Create your first API token to start reading or writing data through the developer API."
                />
              ) : (
                tokens.map((token) => (
                  <div key={token.id} className="rounded-xl border border-border/60 bg-background/60 p-4">
                    <div className="flex flex-wrap items-start justify-between gap-3">
                      <div className="space-y-1">
                        <div className="flex items-center gap-2">
                          <p className="font-medium">{token.name}</p>
                          <Badge variant="outline">{token.access_level === "read_only" ? "Read only" : "Read + write"}</Badge>
                          {token.revoked_at ? <Badge variant="outline">Revoked</Badge> : null}
                        </div>
                        <p className="text-xs text-muted-foreground">
                          Prefix: <span className="font-mono">{token.token_prefix}</span>
                        </p>
                        <p className="text-xs text-muted-foreground">
                          Last used: {formatDate(token.last_used_at)} · Expires: {formatDate(token.expires_at)}
                        </p>
                      </div>
                      {!token.revoked_at ? (
                        <Button variant="outline" size="sm" onClick={() => void handleRevokeToken(token.id)}>
                          Revoke
                        </Button>
                      ) : null}
                    </div>
                  </div>
                ))
              )}
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>Webhook endpoints</CardTitle>
              <CardDescription>Toggle endpoints, inspect recent deliveries, and remove old integrations.</CardDescription>
            </CardHeader>
            <CardContent className="space-y-4">
              {webhooks.length === 0 ? (
                <EmptyState
                  icon={<Link2 className="h-8 w-8" />}
                  title="No webhooks yet"
                  description="Create a webhook endpoint to push project, task, note, and calendar changes into your automation stack."
                />
              ) : (
                webhooks.map((webhook) => (
                  <div key={webhook.id} className="rounded-xl border border-border/60 bg-background/60 p-4 space-y-4">
                    <div className="flex flex-wrap items-start justify-between gap-3">
                      <div className="space-y-1">
                        <div className="flex items-center gap-2">
                          <p className="font-medium">{webhook.name}</p>
                          <Badge variant="outline">{webhook.is_active ? "Active" : "Paused"}</Badge>
                          {webhook.last_response_status ? (
                            <Badge variant="outline">{webhook.last_response_status}</Badge>
                          ) : null}
                        </div>
                        <p className="text-xs text-muted-foreground break-all">{webhook.url}</p>
                        <p className="text-xs text-muted-foreground">
                          Last delivery: {formatDate(webhook.last_delivery_at)}
                        </p>
                      </div>
                      <div className="flex flex-wrap gap-2">
                        <Button
                          variant="outline"
                          size="sm"
                          onClick={() => void handleToggleWebhook(webhook.id, webhook.is_active)}
                        >
                          {webhook.is_active ? "Pause" : "Resume"}
                        </Button>
                        <Button variant="outline" size="sm" onClick={() => void handleLoadDeliveries(webhook.id)}>
                          Load logs
                        </Button>
                        <Button
                          variant="outline"
                          size="sm"
                          onClick={() => void handleSendTestWebhook(webhook.id, webhook.event_types[0])}
                        >
                          Send test
                        </Button>
                        <Button variant="outline" size="sm" onClick={() => void handleDeleteWebhook(webhook.id)}>
                          Delete
                        </Button>
                      </div>
                    </div>

                    <div className="flex flex-wrap gap-2">
                      {webhook.event_types.map((eventType) => (
                        <Badge key={eventType} variant="outline">
                          {eventType}
                        </Badge>
                      ))}
                    </div>

                    {(deliveriesByWebhook[webhook.id] || []).length > 0 ? (
                      <div className="space-y-2 rounded-xl border border-border/60 bg-background p-3">
                        {(deliveriesByWebhook[webhook.id] || []).map((delivery) => (
                          <div
                            key={delivery.id}
                            className="flex flex-wrap items-start justify-between gap-2 border-b border-border/50 pb-2 last:border-b-0 last:pb-0"
                          >
                            <div className="space-y-1">
                              <p className="text-sm font-medium">{delivery.event_type}</p>
                              <p className="text-xs text-muted-foreground">
                                {formatDate(delivery.created_at)}
                              </p>
                              {delivery.response_body ? (
                                <p className="text-xs text-muted-foreground line-clamp-2">
                                  {delivery.response_body}
                                </p>
                              ) : null}
                            </div>
                            <Badge variant="outline">
                              {delivery.success ? "Success" : delivery.response_status || "Failed"}
                            </Badge>
                          </div>
                        ))}
                      </div>
                    ) : null}
                  </div>
                ))
              )}
            </CardContent>
          </Card>
        </div>
      </div>
    </div>
  );
}
