import { useState, type FormEvent } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
  BellRing,
  Check,
  CircleAlert,
  Hash,
  Link2,
  RadioTower,
  Trash2,
} from 'lucide-react';
import { NOTIFICATION_KINDS, type NotificationKind } from '@pig/core';
import { api, get, post } from '@/lib/api';
import {
  Badge,
  Button,
  Card,
  CardContent,
  CardHeader,
  CardTitle,
  EmptyState,
  Input,
  Label as MicroLabel,
} from '@/components/ui';
import { FormField } from '@/components/ui/form-field';
import { Checkbox } from '@/components/ui/checkbox';
import { Label } from '@/components/ui/label';
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';

interface IntegrationReadiness {
  slack: {
    source: 'environment';
    configured: boolean;
    deliveryReady: boolean;
    commandsReady: boolean;
  };
  buzz: {
    source: 'environment';
    configured: boolean;
    deliveryReady: boolean;
    relayUrl: string | null;
    workspaceId: string | null;
  };
}

interface Account {
  id: string;
  name: string;
  side: 'supply' | 'demand' | 'both';
}

interface ChannelLink {
  id: string;
  platform: 'slack' | 'buzz';
  workspaceId: string;
  channelId: string;
  channelName: string | null;
  accountId: string | null;
  notifyOn: NotificationKind[];
  updatedAt: string;
}

interface LinkedChannel {
  link: ChannelLink;
  accountName: string;
}

type Provider = 'slack' | 'buzz';

export function IntegrationSettings() {
  const readiness = useQuery({
    queryKey: ['integration-readiness'],
    queryFn: () => get<IntegrationReadiness>('/api/admin/integrations'),
  });
  const accounts = useQuery({
    queryKey: ['accounts', 'integration-links'],
    queryFn: () => get<Account[]>('/api/accounts'),
  });
  const slackLinks = useQuery({
    queryKey: ['integration-links', 'slack'],
    queryFn: () => get<LinkedChannel[]>('/api/integrations/slack/channel-links'),
  });
  const buzzLinks = useQuery({
    queryKey: ['integration-links', 'buzz'],
    queryFn: () => get<LinkedChannel[]>('/api/integrations/buzz/channel-links'),
    enabled: Boolean(readiness.data?.buzz.configured),
  });

  if (readiness.isLoading || !readiness.data) {
    return <p className="text-sm text-muted">Loading integration readiness…</p>;
  }

  return (
    <div className="flex flex-col gap-5">
      <div className="grid gap-4 lg:grid-cols-2">
        <ProviderCard
          provider="slack"
          title="Slack"
          description="Pipeline movement and idle spend, delivered where the account is discussed."
          configured={readiness.data.slack.configured}
          details={[
            ['Outbound delivery', readiness.data.slack.deliveryReady],
            ['Signed capacity command', readiness.data.slack.commandsReady],
          ]}
        />
        <ProviderCard
          provider="buzz"
          title="Buzz"
          description="Signed PIG events published as the configured workspace identity."
          configured={readiness.data.buzz.configured}
          details={[["Signed relay delivery", readiness.data.buzz.deliveryReady]]}
          metadata={readiness.data.buzz.relayUrl ?? 'Set BUZZ_RELAY_URL on the server'}
        />
      </div>

      <div className="grid gap-5 xl:grid-cols-2">
        <ChannelLinkManager
          provider="slack"
          configured={readiness.data.slack.configured}
          accounts={accounts.data ?? []}
          links={slackLinks.data ?? []}
          linksLoading={slackLinks.isLoading}
        />
        <ChannelLinkManager
          provider="buzz"
          configured={readiness.data.buzz.configured}
          workspaceId={readiness.data.buzz.workspaceId ?? undefined}
          accounts={accounts.data ?? []}
          links={buzzLinks.data ?? []}
          linksLoading={buzzLinks.isLoading}
        />
      </div>

      <p className="flex items-start gap-2 text-xs text-muted">
        <CircleAlert className="mt-0.5 shrink-0" aria-hidden />
        Credentials are environment-only. This page receives readiness signals, never token,
        signing-secret, private-key, or owner-attestation material.
      </p>
    </div>
  );
}

function ProviderCard({
  provider,
  title,
  description,
  configured,
  details,
  metadata,
}: {
  provider: Provider;
  title: string;
  description: string;
  configured: boolean;
  details: [string, boolean][];
  metadata?: string;
}) {
  const Icon = provider === 'slack' ? Hash : RadioTower;
  return (
    <Card className="overflow-hidden">
      <CardHeader className="border-b border-border bg-surface-2">
        <div className="flex items-start justify-between gap-3">
          <div className="flex min-w-0 items-start gap-3">
            <div className="flex size-10 shrink-0 items-center justify-center rounded-xl bg-accent-subtle text-accent-fg">
              <Icon aria-hidden />
            </div>
            <div className="min-w-0">
              <CardTitle className="text-base">{title}</CardTitle>
              <p className="mt-1 text-sm text-muted">{description}</p>
            </div>
          </div>
          <Badge tone={configured ? 'positive' : 'warning'}>
            {configured ? 'Ready' : 'Needs server config'}
          </Badge>
        </div>
      </CardHeader>
      <CardContent className="flex flex-col gap-3 pt-4 sm:pt-5">
        {details.map(([label, ready]) => (
          <div key={label} className="flex min-h-11 items-center justify-between gap-3 text-sm">
            <span>{label}</span>
            <span className={ready ? 'text-positive' : 'text-muted'}>
              {ready ? 'Configured' : 'Unavailable'}
            </span>
          </div>
        ))}
        {metadata ? <p className="break-all text-xs text-muted">{metadata}</p> : null}
        <p className="text-xs text-muted">Source: environment</p>
      </CardContent>
    </Card>
  );
}

function ChannelLinkManager({
  provider,
  configured,
  workspaceId,
  accounts,
  links,
  linksLoading,
}: {
  provider: Provider;
  configured: boolean;
  workspaceId?: string;
  accounts: Account[];
  links: LinkedChannel[];
  linksLoading: boolean;
}) {
  const queryClient = useQueryClient();
  const [workspace, setWorkspace] = useState(workspaceId ?? '');
  const [channelId, setChannelId] = useState('');
  const [channelName, setChannelName] = useState('');
  const [accountId, setAccountId] = useState('');
  const [notifyOn, setNotifyOn] = useState<NotificationKind[]>([...NOTIFICATION_KINDS]);
  const [message, setMessage] = useState<string | null>(null);

  const create = useMutation({
    mutationFn: () =>
      post<ChannelLink>(`/api/integrations/${provider}/channel-links`, {
        ...(provider === 'slack' ? { workspaceId: workspace } : {}),
        channelId,
        channelName: channelName.trim() || null,
        accountId,
        notifyOn,
      }),
    onSuccess: () => {
      setChannelId('');
      setChannelName('');
      setMessage('Channel linked.');
      void queryClient.invalidateQueries({ queryKey: ['integration-links', provider] });
    },
  });
  const remove = useMutation({
    mutationFn: (id: string) =>
      api<{ deleted: true }>(`/api/integrations/${provider}/channel-links/${id}`, {
        method: 'DELETE',
      }),
    onSuccess: () => {
      setMessage('Channel unlinked. Pending deliveries were cancelled.');
      void queryClient.invalidateQueries({ queryKey: ['integration-links', provider] });
    },
  });

  function submit(event: FormEvent) {
    event.preventDefault();
    setMessage(null);
    create.mutate();
  }

  return (
    <Card>
      <CardHeader>
        <div className="flex items-center gap-2">
          <Link2 className="text-accent-fg" aria-hidden />
          <CardTitle className="text-base">
            {provider === 'slack' ? 'Slack channel links' : 'Buzz channel links'}
          </CardTitle>
        </div>
        <p className="text-sm text-muted">
          Link an account to the room where its commercial decisions happen.
        </p>
      </CardHeader>
      <CardContent className="flex flex-col gap-5">
        {!configured ? (
          <div className="rounded-xl border border-border bg-surface-2 p-4 text-sm text-muted">
            Configure this provider on the server before creating links.
          </div>
        ) : (
          <form className="flex flex-col gap-4" onSubmit={submit}>
            {provider === 'slack' ? (
              <FormField label="Workspace ID">
                <Input
                  id="slack-workspace"
                  value={workspace}
                  onChange={(event) => setWorkspace(event.target.value)}
                  placeholder="T0123456789"
                  required
                />
              </FormField>
            ) : (
              <div className="flex min-w-0 flex-col gap-1.5">
                <MicroLabel>Relay workspace</MicroLabel>
                <div className="flex min-h-11 items-center rounded-lg border border-border bg-surface-2 px-3 text-sm text-muted">
                  {workspaceId}
                </div>
              </div>
            )}

            <div className="grid gap-4 sm:grid-cols-2">
              <FormField label={provider === 'slack' ? 'Channel ID' : 'Channel UUID'}>
                <Input
                  id={`${provider}-channel-id`}
                  value={channelId}
                  onChange={(event) => setChannelId(event.target.value)}
                  placeholder={provider === 'slack' ? 'C0123456789' : '00000000-0000-…'}
                  required
                />
              </FormField>
              <FormField label="Display name">
                <Input
                  id={`${provider}-channel-name`}
                  value={channelName}
                  onChange={(event) => setChannelName(event.target.value)}
                  placeholder="gpu-sales"
                />
              </FormField>
            </div>

            <FormField label="Account">
              <Select value={accountId} onValueChange={setAccountId} required>
                <SelectTrigger id={`${provider}-account`}>
                  <SelectValue placeholder="Select an account" />
                </SelectTrigger>
                <SelectContent>
                  <SelectGroup>
                    {accounts.map((account) => (
                      <SelectItem key={account.id} value={account.id}>
                        {account.name} · {account.side}
                      </SelectItem>
                    ))}
                  </SelectGroup>
                </SelectContent>
              </Select>
            </FormField>

            <fieldset className="flex flex-col gap-1.5">
              <MicroLabel as="legend">Notify this channel</MicroLabel>
              <div className="grid gap-2 sm:grid-cols-2">
                {NOTIFICATION_KINDS.map((kind) => {
                  const checked = notifyOn.includes(kind);
                  return (
                    <Label
                      key={kind}
                      className="flex min-h-11 cursor-pointer items-center gap-3 rounded-lg border border-border px-3"
                    >
                      <Checkbox
                        checked={checked}
                        onCheckedChange={(value) => {
                          setNotifyOn((current) =>
                            value ? [...current, kind] : current.filter((item) => item !== kind),
                          );
                        }}
                      />
                      <span className="text-sm">
                        {kind === 'stage_change' ? 'Stage changes' : 'Idle-capacity alerts'}
                      </span>
                    </Label>
                  );
                })}
              </div>
            </fieldset>

            {create.error ? <p role="alert" className="text-sm text-danger">{create.error.message}</p> : null}
            {message ? <p className="flex items-center gap-2 text-sm text-positive"><Check aria-hidden />{message}</p> : null}
            <div>
              <Button
                type="submit"
                variant="primary"
                disabled={create.isPending || !accountId || notifyOn.length === 0}
              >
                <BellRing aria-hidden />
                {create.isPending ? 'Linking…' : 'Link channel'}
              </Button>
            </div>
          </form>
        )}

        <div className="flex flex-col gap-2">
          <MicroLabel as="h4">Linked channels</MicroLabel>
          {linksLoading ? <p className="text-sm text-muted">Loading links…</p> : null}
          {!linksLoading && links.length === 0 ? (
            <EmptyState
              size="inline"
              className="rounded-xl border border-dashed border-border"
              title={`No ${provider === 'slack' ? 'Slack' : 'Buzz'} channels linked yet`}
            />
          ) : null}
          {links.map(({ link, accountName }) => (
            <div
              key={link.id}
              className="flex flex-col gap-3 rounded-xl border border-border p-3 sm:flex-row sm:items-center sm:justify-between"
            >
              <div className="min-w-0">
                <p className="truncate text-sm font-medium">
                  {link.channelName ? `#${link.channelName}` : link.channelId}
                </p>
                <p className="truncate text-xs text-muted">{accountName}</p>
                <div className="mt-2 flex flex-wrap gap-1.5">
                  {link.notifyOn.map((kind) => (
                    <Badge key={kind}>{kind === 'stage_change' ? 'Stages' : 'Idle capacity'}</Badge>
                  ))}
                </div>
              </div>
              <Button
                type="button"
                variant="danger"
                size="icon"
                aria-label={`Unlink ${link.channelName ?? link.channelId}`}
                disabled={remove.isPending}
                onClick={() => remove.mutate(link.id)}
              >
                <Trash2 aria-hidden />
              </Button>
            </div>
          ))}
        </div>
      </CardContent>
    </Card>
  );
}
