'use client';

import { useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { format } from 'date-fns';
import { ExternalLink, RefreshCw, Trash2 } from 'lucide-react';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
} from '@/components/ui/sheet';
import { Spinner } from '@/components/ui/spinners';
import {
  addBrandSocialAccount,
  collectSocialAccountNow,
  fetchBrandSocialAccounts,
  removeBrandSocialAccount,
} from '@/network/apis/dashboard/social-analysis/social-analysis.apis';
import type {
  BrandAccountRelation,
  BrandSocialAccountLink,
  SocialAnalysisBrand,
  SocialPlatform,
} from '@/network/apis/dashboard/social-analysis/social-analysis.types';

const PLATFORMS: { value: SocialPlatform; label: string }[] = [
  { value: 'instagram', label: 'Instagram' },
  { value: 'tiktok', label: 'TikTok' },
  { value: 'snapchat', label: 'Snapchat' },
  { value: 'youtube', label: 'YouTube' },
  { value: 'twitter', label: 'X (Twitter)' },
  { value: 'twitch', label: 'Twitch' },
];

const SOURCE_LABELS: Record<string, string> = {
  brand_accounts: 'From the brand’s accounts',
  social_listening: 'From social listening',
  brand: 'Added by the brand',
  admin: 'Added by an admin',
};

const compact = (n: number | null | undefined) =>
  n === null || n === undefined
    ? '—'
    : new Intl.NumberFormat('en', { notation: 'compact', maximumFractionDigits: 1 }).format(n);

const safeDate = (value: string | null | undefined) => {
  if (!value) return null;
  const d = new Date(value);
  return Number.isNaN(d.getTime()) ? null : format(d, 'dd MMM yyyy');
};

const errorMessage = (error: unknown, fallback: string) => {
  const data = (error as { response?: { data?: { message?: string; errors?: Record<string, string[]> } } })
    ?.response?.data;
  return (data?.errors ? Object.values(data.errors).flat()[0] : null) ?? data?.message ?? fallback;
};

/** One brand's social accounts: see them, add missing ones, remove ones an admin added. */
export function BrandSocialAccountsSheet({
  brand,
  open,
  onClose,
}: {
  brand: SocialAnalysisBrand | null;
  open: boolean;
  onClose: () => void;
}) {
  const qc = useQueryClient();
  const brandId = brand?.id ?? 0;

  const [platform, setPlatform] = useState<SocialPlatform>('instagram');
  const [username, setUsername] = useState('');
  const [relation, setRelation] = useState<BrandAccountRelation>('own');

  const { data: links = [], isLoading } = useQuery({
    queryKey: ['social-analysis-brand-accounts', brandId],
    queryFn: () => fetchBrandSocialAccounts(brandId),
    enabled: open && brandId > 0,
  });

  const refresh = () => {
    qc.invalidateQueries({ queryKey: ['social-analysis-brand-accounts', brandId] });
    qc.invalidateQueries({ queryKey: ['social-analysis-brands'] });
  };

  const add = useMutation({
    mutationFn: () => addBrandSocialAccount(brandId, { platform, username: username.trim(), relation }),
    onSuccess: (link) => {
      toast.success(`Added @${link?.account?.username ?? username.trim()} — it will be collected shortly`);
      setUsername('');
      refresh();
    },
    onError: (e) => toast.error(errorMessage(e, 'Could not add the account')),
  });

  const remove = useMutation({
    mutationFn: (linkId: number) => removeBrandSocialAccount(brandId, linkId),
    onSuccess: () => {
      toast.success('Account removed from this brand');
      refresh();
    },
    onError: (e) => toast.error(errorMessage(e, 'Could not remove the account')),
  });

  const collect = useMutation({
    mutationFn: (accountId: number) => collectSocialAccountNow(accountId),
    onSuccess: () => {
      toast.success('Queued — collected within the next few minutes');
      refresh();
    },
    onError: (e) => toast.error(errorMessage(e, 'Could not queue the account')),
  });

  const own = links.filter((l) => l.relation === 'own');
  const competitors = links.filter((l) => l.relation === 'competitor');

  return (
    <Sheet open={open} onOpenChange={(v) => (v ? null : onClose())}>
      <SheetContent className="w-full sm:max-w-2xl overflow-y-auto">
        <SheetHeader>
          <SheetTitle>{brand?.brand_name || brand?.name || 'Brand'}</SheetTitle>
          <SheetDescription>
            Social accounts collected weekly for this brand. Accounts from social listening and the
            brand&rsquo;s own account list stay in step with those automatically.
          </SheetDescription>
        </SheetHeader>

        <form
          className="mt-4 space-y-3 rounded-lg border p-4"
          onSubmit={(e) => {
            e.preventDefault();
            if (username.trim()) add.mutate();
          }}
        >
          <p className="text-sm font-medium">Add an account</p>
          <div className="grid grid-cols-1 gap-3 sm:grid-cols-[140px_1fr_150px]">
            <div className="space-y-1">
              <Label>Platform</Label>
              <Select value={platform} onValueChange={(v) => setPlatform(v as SocialPlatform)}>
                <SelectTrigger className="h-9">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {PLATFORMS.map((p) => (
                    <SelectItem key={p.value} value={p.value}>
                      {p.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-1">
              <Label>Username or profile link</Label>
              <Input
                dir="ltr"
                className="h-9"
                placeholder="@brand or https://instagram.com/brand"
                value={username}
                onChange={(e) => setUsername(e.target.value)}
              />
            </div>
            <div className="space-y-1">
              <Label>Whose account</Label>
              <Select value={relation} onValueChange={(v) => setRelation(v as BrandAccountRelation)}>
                <SelectTrigger className="h-9">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="own">The brand&rsquo;s own</SelectItem>
                  <SelectItem value="competitor">A competitor</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>
          <div className="flex justify-end">
            <Button type="submit" size="sm" disabled={!username.trim() || add.isPending}>
              {add.isPending ? <Spinner className="me-2 h-4 w-4 animate-spin" /> : null}
              Add account
            </Button>
          </div>
        </form>

        {isLoading ? (
          <div className="flex justify-center py-10">
            <Spinner className="h-6 w-6" />
          </div>
        ) : (
          <div className="mt-6 space-y-6">
            <LinkGroup
              title="Own accounts"
              empty="No own accounts yet — add the brand's handles above so its own growth can be tracked."
              links={own}
              onRemove={(id) => remove.mutate(id)}
              onCollect={(id) => collect.mutate(id)}
              busy={remove.isPending || collect.isPending}
            />
            <LinkGroup
              title="Competitors"
              empty="No competitors tracked. Mention listeners in social listening appear here automatically."
              links={competitors}
              onRemove={(id) => remove.mutate(id)}
              onCollect={(id) => collect.mutate(id)}
              busy={remove.isPending || collect.isPending}
            />
          </div>
        )}
      </SheetContent>
    </Sheet>
  );
}

function LinkGroup({
  title,
  empty,
  links,
  onRemove,
  onCollect,
  busy,
}: {
  title: string;
  empty: string;
  links: BrandSocialAccountLink[];
  onRemove: (linkId: number) => void;
  onCollect: (accountId: number) => void;
  busy: boolean;
}) {
  return (
    <section className="space-y-2">
      <h3 className="text-sm font-semibold">
        {title} <span className="text-muted-foreground font-normal">({links.length})</span>
      </h3>
      {!links.length ? (
        <p className="text-sm text-muted-foreground">{empty}</p>
      ) : (
        <div className="divide-y rounded-lg border">
          {links.map((link) => (
            <AccountRow key={link.id} link={link} onRemove={onRemove} onCollect={onCollect} busy={busy} />
          ))}
        </div>
      )}
    </section>
  );
}

function AccountRow({
  link,
  onRemove,
  onCollect,
  busy,
}: {
  link: BrandSocialAccountLink;
  onRemove: (linkId: number) => void;
  onCollect: (accountId: number) => void;
  busy: boolean;
}) {
  const account = link.account;
  if (!account) return null;

  const collectedOn = safeDate(account.last_collected_at);
  const snapshotOn = safeDate(link.latest?.captured_at);

  return (
    <div className="flex flex-wrap items-center gap-3 p-3">
      {account.avatar_url ? (
        // eslint-disable-next-line @next/next/no-img-element
        <img src={account.avatar_url} alt="" className="h-9 w-9 rounded-full object-cover" />
      ) : (
        <div className="h-9 w-9 rounded-full bg-muted" />
      )}

      <div className="min-w-0 flex-1">
        <div className="flex items-center gap-2">
          <span className="truncate font-medium" dir="ltr">
            @{account.username}
          </span>
          <Badge variant="secondary" appearance="outline" size="sm">
            {account.platform}
          </Badge>
          {account.profile_url ? (
            <a href={account.profile_url} target="_blank" rel="noreferrer" className="text-muted-foreground">
              <ExternalLink className="h-3.5 w-3.5" />
            </a>
          ) : null}
        </div>
        <p className="text-xs text-muted-foreground">
          {SOURCE_LABELS[link.source] ?? link.source}
          {' · '}
          {collectedOn
            ? `Collected ${collectedOn}`
            : account.collection_status === 'empty'
              ? `Nothing to collect: ${account.collection_error ?? 'no report'}`
              : account.collection_status === 'failed'
                ? `Last attempt failed: ${account.collection_error ?? ''}`
                : snapshotOn
                  ? `History from ${snapshotOn}, weekly collection pending`
                  : 'Waiting for its first collection'}
        </p>
      </div>

      <div className="text-end text-sm">
        <div className="font-semibold">{compact(link.latest?.followers)}</div>
        <div className="text-xs text-muted-foreground">
          {link.latest?.engagement_rate != null ? `ER ${link.latest.engagement_rate.toFixed(2)}%` : 'followers'}
        </div>
      </div>

      <div className="flex items-center gap-1">
        <Button
          size="sm"
          variant="ghost"
          title="Collect now"
          disabled={busy}
          onClick={() => onCollect(account.id)}
        >
          <RefreshCw className="h-4 w-4" />
        </Button>
        <Button
          size="sm"
          variant="ghost"
          title={link.removable ? 'Remove from this brand' : 'Change this where it came from'}
          disabled={busy || !link.removable}
          onClick={() => onRemove(link.id)}
        >
          <Trash2 className="h-4 w-4" />
        </Button>
      </div>
    </div>
  );
}
