import JsonViewDialog from '@/components/JsonViewDialog'
import { RefreshButton } from '@/components/RefreshButton'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger
} from '@/components/ui/dropdown-menu'
import SecondaryPageLayout from '@/layouts/SecondaryPageLayout'
import { usePrimaryNoteView } from '@/contexts/primary-note-view-context'
import { buildAccountListRelayUrlsForMerge } from '@/lib/account-list-relay-urls'
import { normalizeTopic } from '@/lib/discussion-topics'
import { toNoteList } from '@/lib/link'
import { fetchLatestReplaceableListEvent } from '@/lib/replaceable-list-latest'
import { cn } from '@/lib/utils'
import { useSmartHashtagNavigation } from '@/PageManager'
import { useInterestList } from '@/providers/InterestListProvider'
import { useNostr } from '@/providers/NostrProvider'
import { useFavoriteRelays } from '@/providers/FavoriteRelaysProvider'
import client from '@/services/client.service'
import { Code, MoreVertical, Trash2 } from 'lucide-react'
import { forwardRef, useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import NotFoundPage from '../NotFoundPage'

const INTEREST_LIST_KIND = 10015

const InterestListPage = forwardRef(
  ({ index, hideTitlebar = false }: { index?: number; hideTitlebar?: boolean }, ref) => {
    const { t } = useTranslation()
    const { registerPrimaryPanelRefresh } = usePrimaryNoteView()
    const { navigateToHashtag } = useSmartHashtagNavigation()
    const { profile, pubkey, interestListEvent, updateInterestListEvent } = useNostr()
    const { favoriteRelays, blockedRelays } = useFavoriteRelays()
    const { subscribedTopics, subscribe, unsubscribe, changing } = useInterestList()
    const [topicInput, setTopicInput] = useState('')
    const [jsonOpen, setJsonOpen] = useState(false)
    const [jsonPayload, setJsonPayload] = useState<unknown>(null)

    const topicsSorted = useMemo(
      () => [...subscribedTopics].sort((a, b) => a.localeCompare(b)),
      [subscribedTopics]
    )

    const refreshFromRelays = useCallback(async () => {
      if (!pubkey) return
      const comprehensiveRelays = await buildAccountListRelayUrlsForMerge({
        accountPubkey: pubkey,
        favoriteRelays: favoriteRelays ?? [],
        blockedRelays
      })
      let latest =
        (await fetchLatestReplaceableListEvent(pubkey, INTEREST_LIST_KIND, comprehensiveRelays)) ?? null
      if (!latest) {
        latest = (await client.fetchInterestListEvent(pubkey)) ?? null
      }
      if (latest) await updateInterestListEvent(latest)
    }, [pubkey, favoriteRelays, blockedRelays, updateInterestListEvent])

    const openJson = useCallback(() => {
      setJsonPayload({
        interestListEvent: interestListEvent ?? null,
        derivedTopics: topicsSorted,
        note: 'Interest list is kind 10015; subscribed topics are stored as `t` tags.'
      })
      setJsonOpen(true)
    }, [interestListEvent, topicsSorted])

    useEffect(() => {
      if (!hideTitlebar) {
        registerPrimaryPanelRefresh(null)
        return
      }
      registerPrimaryPanelRefresh(() => {
        void refreshFromRelays()
      })
      return () => registerPrimaryPanelRefresh(null)
    }, [hideTitlebar, registerPrimaryPanelRefresh, refreshFromRelays])

    const onAddTopic = async (e: React.FormEvent) => {
      e.preventDefault()
      const raw = topicInput.trim().replace(/^#+/u, '')
      const normalized = normalizeTopic(raw)
      if (!normalized) {
        toast.error(t('Interest topic invalid'))
        return
      }
      await subscribe(normalized)
      setTopicInput('')
    }

    if (!profile || !pubkey) {
      return <NotFoundPage />
    }

    return (
      <SecondaryPageLayout
        ref={ref}
        index={index}
        title={
          hideTitlebar
            ? undefined
            : t("username's interest topics", {
                username: profile.username,
                defaultValue: `${profile.username}'s interest topics`
              })
        }
        hideBackButton={hideTitlebar}
        controls={
          hideTitlebar ? undefined : (
            <div className="flex items-center gap-0">
              <RefreshButton onClick={() => void refreshFromRelays()} />
              <DropdownMenu>
                <DropdownMenuTrigger asChild>
                  <Button variant="ghost" size="icon" aria-label={t('More options')}>
                    <MoreVertical className="size-4" />
                  </Button>
                </DropdownMenuTrigger>
                <DropdownMenuContent align="end">
                  <DropdownMenuItem onClick={() => openJson()}>
                    <Code className="mr-2 size-4" />
                    {t('View JSON')}
                  </DropdownMenuItem>
                </DropdownMenuContent>
              </DropdownMenu>
            </div>
          )
        }
        displayScrollToTopButton
      >
        <JsonViewDialog value={jsonPayload} isOpen={jsonOpen} onClose={() => setJsonOpen(false)} />
        <div className="min-w-0 space-y-3 px-3 pb-4 pt-2">
          <p className="text-sm text-muted-foreground">{t('Interests list section subtitle')}</p>
          <form onSubmit={(ev) => void onAddTopic(ev)} className="flex flex-wrap items-center gap-2">
            <Input
              value={topicInput}
              onChange={(ev) => setTopicInput(ev.target.value)}
              placeholder={t('Interest topic placeholder')}
              className="min-w-[12rem] flex-1"
              disabled={changing}
              aria-label={t('Interest topic placeholder')}
            />
            <Button type="submit" disabled={changing || !topicInput.trim()}>
              {t('Interest list add topic')}
            </Button>
          </form>
          {topicsSorted.length === 0 ? (
            <p className="pt-2 text-center text-sm text-muted-foreground">{t('No interest topics in list')}</p>
          ) : (
            <ul className="space-y-1">
              {topicsSorted.map((topic) => (
                <li
                  key={topic}
                  className={cn(
                    'flex min-h-[48px] items-center gap-2 rounded-lg border border-border/60 bg-muted/20 px-3 py-2'
                  )}
                >
                  <button
                    type="button"
                    className="min-w-0 flex-1 truncate text-left text-sm font-medium hover:underline"
                    onClick={() => navigateToHashtag(toNoteList({ hashtag: topic }))}
                  >
                    #{topic}
                  </button>
                  <Button
                    type="button"
                    variant="ghost"
                    size="icon"
                    className="shrink-0"
                    disabled={changing}
                    title={t('Remove from interest list')}
                    aria-label={t('Remove from interest list')}
                    onClick={() => void unsubscribe(topic)}
                  >
                    <Trash2 className="size-4" />
                  </Button>
                </li>
              ))}
            </ul>
          )}
        </div>
      </SecondaryPageLayout>
    )
  }
)

InterestListPage.displayName = 'InterestListPage'
export default InterestListPage
