import { createFileRoute, Link } from "@tanstack/react-router"
import { useState } from "react"
import { useTranslation } from "react-i18next"
import { ArrowLeft, Clock, UserCheck, UserMinus, UserPlus, UserX, Users, X } from "lucide-react"
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Badge } from "@/components/ui/badge"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { toast } from "sonner"
import { useAuth } from "@/components/auth-provider"
import { ActorList } from "@/components/actor-list"
import { ConfirmDialog } from "@/components/confirm-dialog"
import {
  useFollow,
  useFollowing,
  useFollowers,
  usePendingFollowers,
  usePendingFollowing,
  useUnfollow,
  useCancelFollow,
  useAcceptFollower,
  useRejectFollower,
  useRemoveFollower,
  useUserFollowing,
  useUserFollowers,
} from "@/features/social"
import type { RemoteActorDto } from "@/features/social"
import { useDocumentTitle } from "@/hooks/use-document-title"

type SearchParams = { user?: string }

export const Route = createFileRoute("/_app/social")({
  validateSearch: (search: Record<string, unknown>): SearchParams => ({
    user: typeof search.user === "string" ? search.user : undefined,
  }),
  component: SocialPage,
})

function SocialPage() {
  const { t } = useTranslation()
  useDocumentTitle(t("social.title"))
  const { user: viewUserId } = Route.useSearch()
  const { auth } = useAuth()
  const isSelf = !viewUserId || viewUserId === auth?.user_id

  return (
    <div className="space-y-4 p-4">
      <div className="flex items-center gap-3">
        <Link to={isSelf ? "/profile" : "/users/$id"} params={{ id: viewUserId ?? "" }} className="text-muted-foreground">
          <ArrowLeft className="size-5" />
        </Link>
        <h1 className="text-lg font-bold">{t("social.title")}</h1>
      </div>

      {isSelf && <FollowByHandle />}

      {isSelf ? <OwnSocialTabs /> : <UserSocialTabs userId={viewUserId!} />}
    </div>
  )
}

function OwnSocialTabs() {
  const { t } = useTranslation()
  const { data: pendingFollowers } = usePendingFollowers()
  const { data: pendingFollowing } = usePendingFollowing()
  const pendingCount = pendingFollowers?.actors.length ?? 0
  const requestedCount = pendingFollowing?.actors.length ?? 0

  return (
    <Tabs defaultValue="following">
      <TabsList className="w-full">
        <TabsTrigger value="following">{t("social.following")}</TabsTrigger>
        <TabsTrigger value="requested">
          {t("social.requested")}
          {requestedCount > 0 && (
            <Badge variant="secondary" className="ml-1.5 text-[10px]">{requestedCount}</Badge>
          )}
        </TabsTrigger>
        <TabsTrigger value="followers">{t("social.followers")}</TabsTrigger>
        <TabsTrigger value="pending">
          {t("social.pending")}
          {pendingCount > 0 && (
            <Badge variant="secondary" className="ml-1.5 text-[10px]">{pendingCount}</Badge>
          )}
        </TabsTrigger>
      </TabsList>
      <TabsContent value="following"><OwnFollowingTab /></TabsContent>
      <TabsContent value="requested"><RequestedTab /></TabsContent>
      <TabsContent value="followers"><OwnFollowersTab /></TabsContent>
      <TabsContent value="pending"><PendingTab /></TabsContent>
    </Tabs>
  )
}

function UserSocialTabs({ userId }: { userId: string }) {
  const { t } = useTranslation()
  return (
    <Tabs defaultValue="following">
      <TabsList className="w-full">
        <TabsTrigger value="following">{t("social.following")}</TabsTrigger>
        <TabsTrigger value="followers">{t("social.followers")}</TabsTrigger>
      </TabsList>
      <TabsContent value="following"><UserFollowingTab userId={userId} /></TabsContent>
      <TabsContent value="followers"><UserFollowersTab userId={userId} /></TabsContent>
    </Tabs>
  )
}

function OwnFollowingTab() {
  const { t } = useTranslation()
  const { data, isPending } = useFollowing()
  const unfollowMutation = useUnfollow()

  return (
    <ActorList
      data={data}
      isPending={isPending}
      emptyIcon={Users}
      emptyTitle={t("social.notFollowing")}
      emptyDescription={t("social.notFollowingDesc")}
      renderAction={(actor) => (
        <Button
          variant="outline"
          size="sm"
          onClick={() => unfollowMutation.mutate({ actor_url: actor.url })}
          disabled={unfollowMutation.isPending}
        >
          <UserMinus className="mr-1 size-3.5" />
          {t("common.unfollow")}
        </Button>
      )}
    />
  )
}

function OwnFollowersTab() {
  const { t } = useTranslation()
  const { data, isPending } = useFollowers()
  const removeMutation = useRemoveFollower()

  return (
    <ActorList
      data={data}
      isPending={isPending}
      emptyIcon={Users}
      emptyTitle={t("social.noFollowers")}
      renderAction={(actor) => (
        <Button
          variant="ghost"
          size="sm"
          onClick={() => removeMutation.mutate({ actor_url: actor.url })}
          disabled={removeMutation.isPending}
          className="text-destructive hover:text-destructive"
        >
          <UserX className="mr-1 size-3.5" />
          {t("common.remove")}
        </Button>
      )}
    />
  )
}

function PendingTab() {
  const { t } = useTranslation()
  const { data, isPending } = usePendingFollowers()
  const acceptMutation = useAcceptFollower()
  const rejectMutation = useRejectFollower()

  return (
    <ActorList
      data={data}
      isPending={isPending}
      emptyIcon={UserCheck}
      emptyTitle={t("social.noPending")}
      renderAction={(actor) => (
        <div className="flex gap-1">
          <Button size="sm" onClick={() => acceptMutation.mutate({ actor_url: actor.url })} disabled={acceptMutation.isPending}>
            {t("common.accept")}
          </Button>
          <Button variant="outline" size="sm" onClick={() => rejectMutation.mutate({ actor_url: actor.url })} disabled={rejectMutation.isPending}>
            {t("common.reject")}
          </Button>
        </div>
      )}
    />
  )
}

function RequestedTab() {
  const { t } = useTranslation()
  const { data, isPending } = usePendingFollowing()
  const cancelMutation = useCancelFollow()
  const [target, setTarget] = useState<RemoteActorDto | null>(null)

  return (
    <>
      <ActorList
        data={data}
        isPending={isPending}
        emptyIcon={Clock}
        emptyTitle={t("social.noRequested")}
        emptyDescription={t("social.noRequestedDesc")}
        renderAction={(actor) => (
          <div className="flex items-center gap-2">
            <Badge variant="outline" className="text-[10px]">{t("common.requested")}</Badge>
            <Button
              variant="outline"
              size="sm"
              onClick={() => setTarget(actor)}
              disabled={cancelMutation.isPending}
            >
              <X className="mr-1 size-3.5" />
              {t("social.cancelRequest")}
            </Button>
          </div>
        )}
      />
      <ConfirmDialog
        open={!!target}
        onOpenChange={(open) => !open && setTarget(null)}
        title={t("social.cancelRequestConfirm")}
        confirmLabel={t("social.cancelRequest")}
        onConfirm={() => {
          if (target) cancelMutation.mutate({ actor_url: target.url })
          setTarget(null)
        }}
      />
    </>
  )
}

function UserFollowingTab({ userId }: { userId: string }) {
  const { t } = useTranslation()
  const { data, isPending } = useUserFollowing(userId)

  return <ActorList data={data} isPending={isPending} emptyIcon={Users} emptyTitle={t("social.notFollowing")} />
}

function UserFollowersTab({ userId }: { userId: string }) {
  const { t } = useTranslation()
  const { data, isPending } = useUserFollowers(userId)

  return <ActorList data={data} isPending={isPending} emptyIcon={Users} emptyTitle={t("social.noFollowersOther")} />
}

function FollowByHandle() {
  const { t } = useTranslation()
  const [handle, setHandle] = useState("")
  const followMutation = useFollow()

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault()
    if (!handle.trim()) return
    followMutation.mutate(
      { handle: handle.trim() },
      {
        onSuccess: () => {
          toast.success(t("social.followSent", { handle }))
          setHandle("")
        },
        onError: () => {
          toast.error(t("social.followError"))
        },
      },
    )
  }

  return (
    <Card size="sm">
      <CardContent>
        <form onSubmit={handleSubmit} className="flex items-center gap-2">
          <Input
            value={handle}
            onChange={(e) => setHandle(e.target.value)}
            placeholder={t("social.handlePlaceholder")}
            className="flex-1"
          />
          <Button type="submit" size="sm" disabled={!handle.trim() || followMutation.isPending}>
            <UserPlus className="mr-1 size-3.5" />
            {t("common.follow")}
          </Button>
        </form>
      </CardContent>
    </Card>
  )
}
