import { createFileRoute, Link, useNavigate } from "@tanstack/react-router"
import { useTranslation } from "react-i18next"
import { useMutation } from "@tanstack/react-query"
import {
  ArrowLeft,
  BookOpen,
  ChevronRight,
  Download,
  Key,
  List,
  LogOut,
  RefreshCw,
  ShieldBan,
  Sparkles,
  Target,
  Upload,
  User,
} from "lucide-react"
import { Button } from "@/components/ui/button"
import { Switch } from "@/components/ui/switch"
import { useAuth, useIsAdmin } from "@/components/auth-provider"
import { reindexSearch } from "@/features/users"
import { useSettings, useUpdateSettings } from "@/features/goals"
import type { UpdateUserSettingsRequest } from "@/features/goals"
import { useDocumentTitle } from "@/hooks/use-document-title"

export const Route = createFileRoute("/_app/settings/")({
  component: SettingsPage,
})

type SettingsItem = {
  label: string
  description?: string
  to: string
  icon: React.ReactNode
}

function SettingsPage() {
  const { t } = useTranslation()
  useDocumentTitle(t("settings.title"))
  const { logout } = useAuth()
  const isAdmin = useIsAdmin()
  const navigate = useNavigate()

  const account: SettingsItem[] = [
    {
      label: t("settings.editProfile"),
      description: t("settings.editProfileDesc"),
      to: "/settings/edit-profile",
      icon: <User className="size-4" />,
    },
  ]

  const data: SettingsItem[] = [
    {
      label: t("settings.import"),
      description: t("settings.importDesc"),
      to: "/settings/import",
      icon: <Upload className="size-4" />,
    },
    {
      label: t("settings.export"),
      description: t("settings.exportDesc"),
      to: "/settings/export",
      icon: <Download className="size-4" />,
    },
    {
      label: t("settings.yearWrapUp"),
      description: t("settings.yearWrapUpDesc"),
      to: "/settings/wrapup",
      icon: <Sparkles className="size-4" />,
    },
  ]

  const integrations: SettingsItem[] = [
    {
      label: t("settings.webhookTokens"),
      description: t("settings.webhookTokensDesc"),
      to: "/settings/webhooks",
      icon: <Key className="size-4" />,
    },
  ]

  const social: SettingsItem[] = [
    {
      label: isAdmin ? t("settings.blockedUsersAndDomains") : t("settings.blockedUsers"),
      description: isAdmin ? t("settings.blockedUsersDescAdmin") : t("settings.blockedUsersDesc"),
      to: "/settings/blocked",
      icon: <ShieldBan className="size-4" />,
    },
  ]

  const handleLogout = () => {
    logout()
    navigate({ to: "/login" })
  }

  return (
    <div className="space-y-6 p-4">
      <div className="flex items-center gap-3">
        <Link to="/profile" className="text-muted-foreground">
          <ArrowLeft className="size-5" />
        </Link>
        <h1 className="text-lg font-bold">{t("settings.title")}</h1>
      </div>

      <SettingsGroup label={t("settings.account")} items={account} />
      <SettingsGroup label={t("settings.data")} items={data} />
      <SettingsGroup label={t("settings.integrations")} items={integrations} />
      <SettingsGroup label={t("settings.socialGroup")} items={social} />

      <PrivacySection />

      {isAdmin && <AdminActions />}

      <Button
        variant="ghost"
        onClick={handleLogout}
        className="w-full justify-start gap-3 rounded-xl bg-card p-3 text-red-400 hover:text-red-300"
      >
        <LogOut className="size-4" />
        {t("settings.logOut")}
      </Button>
    </div>
  )
}

function PrivacySection() {
  const { t } = useTranslation()
  const { data: settings } = useSettings()
  const updateMutation = useUpdateSettings()

  const disabled = updateMutation.isPending

  const toggle = (patch: Partial<UpdateUserSettingsRequest>) => {
    if (!settings) return
    updateMutation.mutate({
      federate_goals: settings.federate_goals,
      federate_reviews: settings.federate_reviews,
      federate_watchlist: settings.federate_watchlist,
      ...patch,
    })
  }

  return (
    <div>
      <p className="mb-1.5 px-1 text-xs font-medium text-muted-foreground">
        {t("settings.privacy")}
      </p>
      <div className="divide-y divide-border rounded-xl bg-card">
        <div className="flex items-center gap-3 p-3">
          <span className="text-muted-foreground">
            <Target className="size-4" />
          </span>
          <div className="flex-1">
            <p className="text-sm font-medium">{t("settings.federateGoals")}</p>
            <p className="text-xs text-muted-foreground">
              {t("settings.federateGoalsDesc")}
            </p>
          </div>
          <Switch
            checked={settings?.federate_goals ?? true}
            onCheckedChange={(checked) => toggle({ federate_goals: checked })}
            disabled={disabled}
          />
        </div>
        <div className="flex items-center gap-3 p-3">
          <span className="text-muted-foreground">
            <BookOpen className="size-4" />
          </span>
          <div className="flex-1">
            <p className="text-sm font-medium">{t("settings.federateReviews")}</p>
            <p className="text-xs text-muted-foreground">
              {t("settings.federateReviewsDesc")}
            </p>
          </div>
          <Switch
            checked={settings?.federate_reviews ?? true}
            onCheckedChange={(checked) => toggle({ federate_reviews: checked })}
            disabled={disabled}
          />
        </div>
        <div className="flex items-center gap-3 p-3">
          <span className="text-muted-foreground">
            <List className="size-4" />
          </span>
          <div className="flex-1">
            <p className="text-sm font-medium">{t("settings.federateWatchlist")}</p>
            <p className="text-xs text-muted-foreground">
              {t("settings.federateWatchlistDesc")}
            </p>
          </div>
          <Switch
            checked={settings?.federate_watchlist ?? true}
            onCheckedChange={(checked) => toggle({ federate_watchlist: checked })}
            disabled={disabled}
          />
        </div>
      </div>
    </div>
  )
}

function AdminActions() {
  const { t } = useTranslation()
  const reindex = useMutation({
    mutationFn: reindexSearch,
  })

  return (
    <div>
      <p className="mb-1.5 px-1 text-xs font-medium text-muted-foreground">
        {t("settings.admin")}
      </p>
      <div className="divide-y divide-border rounded-xl bg-card">
        <div className="flex items-center gap-3 p-3">
          <span className="text-muted-foreground">
            <RefreshCw className={`size-4 ${reindex.isPending ? "animate-spin" : ""}`} />
          </span>
          <div className="flex-1">
            <p className="text-sm font-medium">{t("settings.rebuildSearch")}</p>
            <p className="text-xs text-muted-foreground">
              {reindex.isSuccess ? t("settings.rebuildSearchDone") : t("settings.rebuildSearchDesc")}
            </p>
          </div>
          <Button variant="outline" size="sm" onClick={() => reindex.mutate()} disabled={reindex.isPending}>
            {reindex.isPending ? t("common.generating") : t("common.run")}
          </Button>
        </div>
      </div>
    </div>
  )
}

function SettingsGroup({
  label,
  items,
}: {
  label: string
  items: SettingsItem[]
}) {
  return (
    <div>
      <p className="mb-1.5 px-1 text-xs font-medium text-muted-foreground">
        {label}
      </p>
      <div className="divide-y divide-border rounded-xl bg-card">
        {items.map((item) => (
          <Link
            key={item.label}
            to={item.to}
            className="flex items-center gap-3 p-3"
          >
            <span className="text-muted-foreground">{item.icon}</span>
            <div className="flex-1">
              <p className="text-sm font-medium">{item.label}</p>
              {item.description && (
                <p className="text-xs text-muted-foreground">
                  {item.description}
                </p>
              )}
            </div>
            <ChevronRight className="size-4 text-muted-foreground" />
          </Link>
        ))}
      </div>
    </div>
  )
}
