'use client'

import { useTransition } from 'react'
import { useRouter } from 'next/navigation'
import { toast } from 'sonner'
import { Button } from '@/components/ui/button'
import { useProductWorkspaceStore } from '@/stores/product-workspace/store'
import {
  selectIsDirty,
  selectPendingCount,
} from '@/stores/product-workspace/selectors'
import { commitSprintMembershipAction } from '@/actions/sprints'

interface SaveSprintButtonProps {
  activeSprintId: string
}

/**
 * PBI-79 / ST-1338 / T-940: 'Sprint opslaan'-knop voor state B.
 * Altijd zichtbaar zolang er een actieve sprint is. Disabled bij clean,
 * enabled met teller bij dirty. Commit gebeurt via
 * commitSprintMembershipAction; client patcht gericht via
 * applyMembershipCommitResult. Geen router.refresh.
 */
export function SaveSprintButton({ activeSprintId }: SaveSprintButtonProps) {
  const router = useRouter()
  const isDirty = useProductWorkspaceStore(selectIsDirty)
  const count = useProductWorkspaceStore(selectPendingCount)
  const adds = useProductWorkspaceStore((s) => s.sprintMembership.pending.adds)
  const removes = useProductWorkspaceStore(
    (s) => s.sprintMembership.pending.removes,
  )
  const applyMembershipCommitResult = useProductWorkspaceStore(
    (s) => s.applyMembershipCommitResult,
  )
  const [isPending, startTransition] = useTransition()

  function handleSave() {
    startTransition(async () => {
      const result = await commitSprintMembershipAction({
        activeSprintId,
        adds: [...adds],
        removes: [...removes],
      })
      if ('error' in result) {
        toast.error(result.error)
        return
      }
      applyMembershipCommitResult({
        activeSprintId,
        addedStoryIds: adds.filter((id) =>
          result.affectedStoryIds.includes(id),
        ),
        removedStoryIds: removes.filter((id) =>
          result.affectedStoryIds.includes(id),
        ),
      })
      const skipped =
        result.conflicts.notEligible.length +
        result.conflicts.alreadyRemoved.length
      if (skipped > 0) {
        toast.warning(
          `${skipped} wijziging${skipped === 1 ? '' : 'en'} overgeslagen — story al in andere sprint of inmiddels verwijderd.`,
        )
      } else {
        toast.success('Sprint opgeslagen')
      }
      // Gericht patchen voldoende voor lokale UI; refresh haalt server-side
      // counts opnieuw op zodat tri-state in volgende renders klopt.
      router.refresh()
    })
  }

  return (
    <Button
      type="button"
      size="sm"
      onClick={handleSave}
      disabled={!isDirty || isPending}
      data-debug-id="save-sprint-button"
    >
      {isPending
        ? 'Opslaan…'
        : isDirty
        ? `Sprint opslaan (${count})`
        : 'Sprint opslaan'}
    </Button>
  )
}
