import { useState } from 'react'
import { createFileRoute } from '@tanstack/react-router'
import { Pencil, Plus, RefreshCw, Trash2 } from 'lucide-react'
import { trpc } from '@/lib/trpc'
import { Card, CardContent } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Skeleton } from '@/components/Skeleton'
import { RegisterProjectDialog } from '@/components/RegisterProjectDialog'
import { toast } from 'sonner'

export const Route = createFileRoute('/settings/projects')({
  component: ProjectsSettingsPage,
})

function ProjectsSettingsPage() {
  const [registerOpen, setRegisterOpen] = useState(false)

  const projectsQuery = trpc.listProjects.useQuery()
  const utils = trpc.useUtils()

  const deleteMutation = trpc.deleteProject.useMutation({
    onSuccess: () => {
      void utils.listProjects.invalidate()
      toast.success('Project deleted')
    },
    onError: (err) => {
      toast.error(`Failed to delete project: ${err.message}`)
    },
  })

  const { data: projects, isLoading } = projectsQuery

  if (isLoading) {
    return (
      <div className="space-y-6">
        <Skeleton className="h-9 w-36" />
        <Skeleton className="h-24 w-full" />
        <Skeleton className="h-24 w-full" />
      </div>
    )
  }

  return (
    <div className="space-y-6">
      <div className="flex justify-end">
        <Button size="sm" onClick={() => setRegisterOpen(true)}>
          <Plus className="mr-2 h-4 w-4" />
          Register Project
        </Button>
      </div>

      {!projects || projects.length === 0 ? (
        <Card>
          <CardContent className="py-8">
            <p className="text-center text-sm text-muted-foreground">
              No projects registered yet.
            </p>
            <div className="mt-4 flex justify-center">
              <Button
                variant="outline"
                size="sm"
                onClick={() => setRegisterOpen(true)}
              >
                Register Project
              </Button>
            </div>
          </CardContent>
        </Card>
      ) : (
        projects.map((project) => (
          <ProjectCard
            key={project.id}
            project={project}
            onDelete={() => {
              if (window.confirm(`Delete project "${project.name}"? This will also remove the cloned repository.`)) {
                deleteMutation.mutate({ id: project.id })
              }
            }}
          />
        ))
      )}

      <RegisterProjectDialog
        open={registerOpen}
        onOpenChange={(open) => {
          setRegisterOpen(open)
          if (!open) void utils.listProjects.invalidate()
        }}
      />
    </div>
  )
}

function formatRelativeTime(date: Date | string | null): string {
  if (!date) return 'never synced'
  const d = typeof date === 'string' ? new Date(date) : date
  const seconds = Math.floor((Date.now() - d.getTime()) / 1000)
  if (seconds < 60) return 'just now'
  const minutes = Math.floor(seconds / 60)
  if (minutes < 60) return `${minutes}m ago`
  const hours = Math.floor(minutes / 60)
  if (hours < 24) return `${hours}h ago`
  const days = Math.floor(hours / 24)
  return `${days}d ago`
}

function ProjectCard({
  project,
  onDelete,
}: {
  project: { id: string; name: string; url: string; defaultBranch: string; lastFetchedAt: Date | null }
  onDelete: () => void
}) {
  const [editing, setEditing] = useState(false)
  const [editValue, setEditValue] = useState(project.defaultBranch)

  const utils = trpc.useUtils()

  const updateMutation = trpc.updateProject.useMutation({
    onSuccess: () => {
      void utils.listProjects.invalidate()
      setEditing(false)
      toast.success('Default branch updated')
    },
    onError: (err) => {
      toast.error(`Failed to update: ${err.message}`)
    },
  })

  const syncMutation = trpc.syncProject.useMutation({
    onSuccess: (result) => {
      void utils.listProjects.invalidate()
      void utils.getProjectSyncStatus.invalidate({ id: project.id })
      if (result.success) {
        toast.success(`Synced ${result.projectName}`)
      } else {
        toast.error(`Sync failed: ${result.error}`)
      }
    },
    onError: (err) => {
      toast.error(`Sync failed: ${err.message}`)
    },
  })

  const syncStatusQuery = trpc.getProjectSyncStatus.useQuery(
    { id: project.id },
    { refetchInterval: 60_000 },
  )

  function saveEdit() {
    const trimmed = editValue.trim()
    if (!trimmed || trimmed === project.defaultBranch) {
      setEditing(false)
      setEditValue(project.defaultBranch)
      return
    }
    updateMutation.mutate({ id: project.id, defaultBranch: trimmed })
  }

  const syncStatus = syncStatusQuery.data

  return (
    <Card>
      <CardContent className="flex items-center gap-4 py-4">
        <div className="min-w-0 flex-1 space-y-1">
          <p className="text-sm font-semibold">{project.name}</p>
          <p className="truncate text-xs text-muted-foreground">
            {project.url}
          </p>
          <div className="flex items-center gap-2 text-xs">
            <span className="text-muted-foreground">Default branch:</span>
            {editing ? (
              <Input
                className="h-6 w-40 text-xs"
                value={editValue}
                onChange={(e) => setEditValue(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === 'Enter') saveEdit()
                  if (e.key === 'Escape') {
                    setEditing(false)
                    setEditValue(project.defaultBranch)
                  }
                }}
                onBlur={saveEdit}
                autoFocus
                disabled={updateMutation.isPending}
              />
            ) : (
              <button
                className="inline-flex items-center gap-1 rounded px-1 py-0.5 font-mono hover:bg-muted"
                onClick={() => {
                  setEditValue(project.defaultBranch)
                  setEditing(true)
                }}
              >
                {project.defaultBranch}
                <Pencil className="h-3 w-3 text-muted-foreground" />
              </button>
            )}
          </div>
          <div className="flex items-center gap-3 text-xs text-muted-foreground">
            <span>Synced: {formatRelativeTime(project.lastFetchedAt)}</span>
            {syncStatus && (syncStatus.ahead > 0 || syncStatus.behind > 0) && (
              <span className="font-mono">
                {syncStatus.ahead > 0 && <span className="text-status-success-fg">+{syncStatus.ahead}</span>}
                {syncStatus.ahead > 0 && syncStatus.behind > 0 && ' / '}
                {syncStatus.behind > 0 && <span className="text-status-warning-fg">-{syncStatus.behind}</span>}
              </span>
            )}
          </div>
        </div>
        <Button
          variant="ghost"
          size="icon"
          className="shrink-0 text-muted-foreground"
          onClick={() => syncMutation.mutate({ id: project.id })}
          disabled={syncMutation.isPending}
          title="Sync from remote"
        >
          <RefreshCw className={`h-4 w-4 ${syncMutation.isPending ? 'animate-spin' : ''}`} />
        </Button>
        <Button
          variant="ghost"
          size="icon"
          className="shrink-0 text-muted-foreground hover:text-destructive"
          onClick={onDelete}
        >
          <Trash2 className="h-4 w-4" />
        </Button>
      </CardContent>
    </Card>
  )
}
