"use client"

import { useState } from "react"
import { useSubscriptions } from "@/lib/queries/use-subscriptions"
import {
  useUpdateSubscriptionTitle,
  useUpdateSubscriptionHiddenFromTimeline,
  useUpdateFeedUrl,
  useUpdateFeedCredentials,
  useAddFeedCredentials,
  useMoveSubscriptionToFolder,
  useUnsubscribe,
  useRequestFeedRefresh,
} from "@/lib/queries/use-subscription-mutations"
import { useUserProfile } from "@/lib/queries/use-user-profile"
import { useUserInterfaceStore } from "@/lib/stores/user-interface-store"
import { TIER_LIMITS } from "@asa-news/shared"
import type { Subscription } from "@/lib/types/subscription"

function formatRelativeTime(isoString: string | null): string {
  if (!isoString) return "never"
  const date = new Date(isoString)
  const now = new Date()
  const differenceSeconds = Math.floor((now.getTime() - date.getTime()) / 1000)
  if (differenceSeconds < 60) return "just now"
  if (differenceSeconds < 3600) return `${Math.floor(differenceSeconds / 60)}m ago`
  if (differenceSeconds < 86400) return `${Math.floor(differenceSeconds / 3600)}h ago`
  return `${Math.floor(differenceSeconds / 86400)}d ago`
}

function formatRefreshInterval(seconds: number): string {
  if (seconds < 3600) return `${Math.round(seconds / 60)} min`
  return `${Math.round(seconds / 3600)} hr`
}

function SubscriptionRow({
  subscription,
  folderOptions,
}: {
  subscription: Subscription
  folderOptions: { identifier: string; name: string }[]
}) {
  const [isEditingTitle, setIsEditingTitle] = useState(false)
  const [editedTitle, setEditedTitle] = useState(
    subscription.customTitle ?? ""
  )
  const [isEditingUrl, setIsEditingUrl] = useState(false)
  const [editedUrl, setEditedUrl] = useState(subscription.feedUrl)
  const [showUnsubscribeConfirm, setShowUnsubscribeConfirm] = useState(false)
  const [isEditingCredentials, setIsEditingCredentials] = useState(false)
  const [editedAuthType, setEditedAuthType] = useState("bearer")
  const [editedCredential, setEditedCredential] = useState("")
  const updateTitle = useUpdateSubscriptionTitle()
  const updateHiddenFromTimeline = useUpdateSubscriptionHiddenFromTimeline()
  const updateFeedUrl = useUpdateFeedUrl()
  const updateCredentials = useUpdateFeedCredentials()
  const addCredentials = useAddFeedCredentials()
  const moveToFolder = useMoveSubscriptionToFolder()
  const unsubscribe = useUnsubscribe()
  const requestRefresh = useRequestFeedRefresh()
  const { data: userProfile } = useUserProfile()

  function handleSaveTitle() {
    const trimmedTitle = editedTitle.trim()
    updateTitle.mutate({
      subscriptionIdentifier: subscription.subscriptionIdentifier,
      customTitle: trimmedTitle || null,
    })
    setIsEditingTitle(false)
  }

  function handleSaveUrl() {
    const trimmedUrl = editedUrl.trim()
    if (!trimmedUrl || trimmedUrl === subscription.feedUrl) {
      setIsEditingUrl(false)
      return
    }
    updateFeedUrl.mutate({
      feedIdentifier: subscription.feedIdentifier,
      feedUrl: trimmedUrl,
    })
    setIsEditingUrl(false)
  }

  function handleSaveCredentials() {
    const trimmedCredential = editedCredential.trim()
    if (!trimmedCredential) return

    if (subscription.feedVisibility === "authenticated") {
      updateCredentials.mutate({
        feedIdentifier: subscription.feedIdentifier,
        authenticationType: editedAuthType,
        credential: trimmedCredential,
      })
    } else {
      addCredentials.mutate({
        subscriptionIdentifier: subscription.subscriptionIdentifier,
        authenticationType: editedAuthType,
        credential: trimmedCredential,
      })
    }
    setIsEditingCredentials(false)
    setEditedCredential("")
  }

  function handleFolderChange(folderIdentifier: string) {
    const sourceFolder = folderOptions.find(
      (folder) => folder.identifier === subscription.folderIdentifier
    )
    const targetFolder = folderOptions.find(
      (folder) => folder.identifier === folderIdentifier
    )
    moveToFolder.mutate({
      subscriptionIdentifier: subscription.subscriptionIdentifier,
      folderIdentifier: folderIdentifier || null,
      feedTitle: subscription.customTitle ?? subscription.feedTitle ?? undefined,
      sourceFolderName: sourceFolder?.name,
      folderName: targetFolder?.name,
    })
  }

  return (
    <div className="flex flex-col gap-2 border-b border-border px-4 py-3 last:border-b-0">
      <div className="flex items-center justify-between gap-4">
        <div className="min-w-0 flex-1">
          {isEditingTitle ? (
            <div className="flex items-center gap-2">
              <input
                type="text"
                value={editedTitle}
                onChange={(event) => setEditedTitle(event.target.value)}
                placeholder={subscription.feedTitle}
                className="min-w-0 flex-1 border border-border bg-background-primary px-2 py-1 text-text-primary outline-none focus:border-text-dim"
                onKeyDown={(event) => {
                  if (event.key === "Enter") handleSaveTitle()
                  if (event.key === "Escape") setIsEditingTitle(false)
                }}
                autoFocus
              />
              <button
                onClick={handleSaveTitle}
                className="px-2 py-1 text-text-secondary transition-colors hover:text-text-primary"
              >
                save
              </button>
              <button
                onClick={() => setIsEditingTitle(false)}
                className="px-2 py-1 text-text-secondary transition-colors hover:text-text-primary"
              >
                cancel
              </button>
            </div>
          ) : (
            <div className="flex items-center gap-2">
              <span className="truncate text-text-primary">
                {subscription.customTitle ?? subscription.feedTitle}
              </span>
              {subscription.feedVisibility === "authenticated" && (
                <span className="shrink-0 text-text-dim">[auth]</span>
              )}
              <button
                onClick={() => {
                  setEditedTitle(subscription.customTitle ?? "")
                  setIsEditingTitle(true)
                }}
                className="shrink-0 px-2 py-1 text-text-dim transition-colors hover:text-text-secondary"
              >
                rename
              </button>
            </div>
          )}
          {isEditingUrl ? (
            <div className="flex items-center gap-2">
              <input
                type="text"
                value={editedUrl}
                onChange={(event) => setEditedUrl(event.target.value)}
                className="min-w-0 flex-1 border border-border bg-background-primary px-2 py-1 text-text-primary outline-none focus:border-text-dim"
                onKeyDown={(event) => {
                  if (event.key === "Enter") handleSaveUrl()
                  if (event.key === "Escape") setIsEditingUrl(false)
                }}
                autoFocus
              />
              <button
                onClick={handleSaveUrl}
                className="px-2 py-1 text-text-secondary transition-colors hover:text-text-primary"
              >
                save
              </button>
              <button
                onClick={() => {
                  setEditedUrl(subscription.feedUrl)
                  setIsEditingUrl(false)
                }}
                className="px-2 py-1 text-text-secondary transition-colors hover:text-text-primary"
              >
                cancel
              </button>
            </div>
          ) : (
            <div className="flex items-center gap-2">
              <p className="min-w-0 truncate text-text-dim">{subscription.feedUrl}</p>
              <button
                onClick={() => {
                  setEditedUrl(subscription.feedUrl)
                  setIsEditingUrl(true)
                }}
                className="shrink-0 px-2 py-1 text-text-dim transition-colors hover:text-text-secondary"
              >
                edit url
              </button>
            </div>
          )}
          <div className="mt-1 flex flex-wrap gap-x-3 gap-y-0.5 text-text-dim">
            <span>last fetched: {formatRelativeTime(subscription.lastFetchedAt)}</span>
            <span>interval: {formatRefreshInterval(subscription.fetchIntervalSeconds)}</span>
            {subscription.consecutiveFailures > 0 && (
              <span className="text-status-warning">
                {subscription.consecutiveFailures} consecutive failure{subscription.consecutiveFailures !== 1 && "s"}
              </span>
            )}
          </div>
          {subscription.lastFetchError && subscription.consecutiveFailures > 0 && (
            <p className="mt-1 truncate text-status-warning">
              {subscription.lastFetchError}
            </p>
          )}
        </div>
      </div>
      {isEditingCredentials ? (
        <div className="flex items-center gap-2">
          <select
            value={editedAuthType}
            onChange={(event) => setEditedAuthType(event.target.value)}
            className="border border-border bg-background-primary px-2 py-1 text-text-secondary outline-none"
          >
            <option value="bearer">bearer token</option>
            <option value="basic">basic (user:pass)</option>
            <option value="query_param">query parameter</option>
          </select>
          <input
            type="password"
            value={editedCredential}
            onChange={(event) => setEditedCredential(event.target.value)}
            placeholder={
              editedAuthType === "query_param"
                ? "api_key=your_token"
                : editedAuthType === "basic"
                  ? "username:password"
                  : "your token"
            }
            className="min-w-0 flex-1 border border-border bg-background-primary px-2 py-1 text-text-primary outline-none placeholder:text-text-dim focus:border-text-dim"
            onKeyDown={(event) => {
              if (event.key === "Enter" && editedCredential.trim()) {
                handleSaveCredentials()
              }
              if (event.key === "Escape") {
                setIsEditingCredentials(false)
                setEditedCredential("")
              }
            }}
            autoFocus
          />
          <button
            onClick={handleSaveCredentials}
            disabled={!editedCredential.trim()}
            className="px-2 py-1 text-text-secondary transition-colors hover:text-text-primary disabled:opacity-50"
          >
            save
          </button>
          <button
            onClick={() => {
              setIsEditingCredentials(false)
              setEditedCredential("")
            }}
            className="px-2 py-1 text-text-secondary transition-colors hover:text-text-primary"
          >
            cancel
          </button>
        </div>
      ) : null}
      <div className="flex flex-wrap items-center gap-2">
        <select
          value={subscription.folderIdentifier ?? ""}
          onChange={(event) => handleFolderChange(event.target.value)}
          className="border border-border bg-background-primary px-2 py-1 text-text-secondary outline-none"
        >
          <option value="">no folder</option>
          {folderOptions.map((folder) => (
            <option key={folder.identifier} value={folder.identifier}>
              {folder.name}
            </option>
          ))}
        </select>
        <button
          onClick={() =>
            updateHiddenFromTimeline.mutate({
              subscriptionIdentifier: subscription.subscriptionIdentifier,
              hiddenFromTimeline: !subscription.hiddenFromTimeline,
            })
          }
          disabled={updateHiddenFromTimeline.isPending}
          className={
            subscription.hiddenFromTimeline
              ? "px-2 py-1 text-text-dim transition-colors hover:text-text-secondary disabled:opacity-50"
              : "px-2 py-1 text-text-secondary transition-colors hover:text-text-primary disabled:opacity-50"
          }
        >
          {subscription.hiddenFromTimeline ? "hidden from timeline" : "hide from timeline"}
        </button>
        {(userProfile?.tier === "pro" || userProfile?.tier === "developer") && (
          <button
            onClick={() =>
              requestRefresh.mutate({
                subscriptionIdentifier:
                  subscription.subscriptionIdentifier,
              })
            }
            disabled={requestRefresh.isPending}
            className="px-2 py-1 text-text-secondary transition-colors hover:text-text-primary disabled:opacity-50"
          >
            refresh
          </button>
        )}
        {(userProfile?.tier === "pro" || userProfile?.tier === "developer") && !isEditingCredentials && (
          <button
            onClick={() => setIsEditingCredentials(true)}
            className="px-2 py-1 text-text-secondary transition-colors hover:text-text-primary"
          >
            {subscription.feedVisibility === "authenticated" ? "update credentials" : "add credentials"}
          </button>
        )}
        {showUnsubscribeConfirm ? (
          <div className="flex items-center gap-1">
            <span className="text-text-dim">confirm?</span>
            <button
              onClick={() => {
                unsubscribe.mutate({
                  subscriptionIdentifier:
                    subscription.subscriptionIdentifier,
                  feedTitle:
                    subscription.customTitle ?? subscription.feedTitle ?? subscription.feedUrl,
                })
                setShowUnsubscribeConfirm(false)
              }}
              className="px-2 py-1 text-status-error transition-colors hover:text-text-primary"
            >
              yes
            </button>
            <button
              onClick={() => setShowUnsubscribeConfirm(false)}
              className="px-2 py-1 text-text-secondary transition-colors hover:text-text-primary"
            >
              no
            </button>
          </div>
        ) : (
          <button
            onClick={() => setShowUnsubscribeConfirm(true)}
            className="px-2 py-1 text-text-secondary transition-colors hover:text-status-error"
          >
            unsubscribe
          </button>
        )}
      </div>
    </div>
  )
}

export function SubscriptionsSettings() {
  const { data: subscriptionsData, isLoading } = useSubscriptions()
  const { data: userProfile } = useUserProfile()
  const setAddFeedDialogOpen = useUserInterfaceStore(
    (state) => state.setAddFeedDialogOpen
  )
  const [searchQuery, setSearchQuery] = useState("")
  const [folderFilter, setFolderFilter] = useState<string>("all")

  if (isLoading) {
    return <p className="px-4 py-6 text-text-dim">loading subscriptions ...</p>
  }

  const subscriptions = subscriptionsData?.subscriptions ?? []
  const folders = subscriptionsData?.folders ?? []
  const folderOptions = folders.map((folder) => ({
    identifier: folder.folderIdentifier,
    name: folder.name,
  }))

  if (subscriptions.length === 0) {
    return (
      <p className="px-4 py-6 text-text-dim">
        no subscriptions yet — add a feed to get started
      </p>
    )
  }

  const normalizedQuery = searchQuery.toLowerCase().trim()

  const filteredSubscriptions = subscriptions.filter((subscription) => {
    if (folderFilter === "ungrouped" && subscription.folderIdentifier !== null) return false
    if (folderFilter !== "all" && folderFilter !== "ungrouped" && subscription.folderIdentifier !== folderFilter) return false

    if (normalizedQuery) {
      const title = (subscription.customTitle ?? subscription.feedTitle ?? "").toLowerCase()
      const url = (subscription.feedUrl ?? "").toLowerCase()
      if (!title.includes(normalizedQuery) && !url.includes(normalizedQuery)) return false
    }

    return true
  })

  return (
    <div>
      <div className="flex flex-wrap items-center gap-2 px-4 py-3">
        <input
          type="text"
          value={searchQuery}
          onChange={(event) => setSearchQuery(event.target.value)}
          placeholder="search subscriptions..."
          className="min-w-0 flex-1 border border-border bg-background-primary px-3 py-1.5 text-text-primary outline-none placeholder:text-text-dim focus:border-text-dim"
        />
        <select
          value={folderFilter}
          onChange={(event) => setFolderFilter(event.target.value)}
          className="border border-border bg-background-primary px-2 py-1.5 text-text-secondary outline-none"
        >
          <option value="all">all folders</option>
          <option value="ungrouped">ungrouped</option>
          {folderOptions.map((folder) => (
            <option key={folder.identifier} value={folder.identifier}>
              {folder.name}
            </option>
          ))}
        </select>
        <span className="text-text-dim">
          {filteredSubscriptions.length} / {TIER_LIMITS[userProfile?.tier ?? "free"].maximumFeeds}
        </span>
        <button
          type="button"
          onClick={() => setAddFeedDialogOpen(true)}
          className="border border-border bg-background-tertiary px-3 py-1.5 text-text-primary transition-colors hover:bg-border"
        >
          + add feed
        </button>
      </div>
      <div>
        {filteredSubscriptions.map((subscription) => (
          <SubscriptionRow
            key={subscription.subscriptionIdentifier}
            subscription={subscription}
            folderOptions={folderOptions}
          />
        ))}
        {filteredSubscriptions.length === 0 && (
          <p className="px-4 py-6 text-text-dim">no subscriptions match your filters</p>
        )}
      </div>
    </div>
  )
}
