'use client'

import { useEffect, useState } from 'react'
import { LayoutTemplate, Plus } from 'lucide-react'
import { fetchPosts, type PostType } from '../../lib/posts-service.js'
import { paletteFor } from '../../components/posts/badges.js'
import { resolvePostTypeIcon } from '../../components/posts/icons.js'

/**
 * Post Types — card grid that mirrors the reference screenshot. Each
 * card surfaces:
 *   - colored top border (accent)
 *   - icon badge in upper-left
 *   - title + description
 *   - footer row: post count · field count · URL base
 *
 * Clicking a card opens that type's settings (`/posts/types/:slug/edit`);
 * each card also has an "Edit Template" action (`/posts/types/:slug/template`)
 * for the type's default layout. The dashed "+ New Post Type" card routes to
 * `/posts/types/new`, where users get instructions for adding a new collection
 * to the config file.
 *
 * Why no in-app create/edit flow yet:
 *   Collections are file-defined (actuate.config.ts). Writing to that
 *   file at runtime would require a parallel data model and break the
 *   read-only deploy invariant on serverless platforms. v2 of this
 *   surface will introduce a DB-overlay for visual metadata (icon /
 *   color / description) — schema stays in code.
 */

interface PostTypesViewProps {
  onNavigate: (path: string) => void
}

export function PostTypesView({ onNavigate }: PostTypesViewProps) {
  const [types, setTypes] = useState<PostType[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [refreshToken, setRefreshToken] = useState(0)

  useEffect(() => {
    let cancelled = false
    setLoading(true)
    setError(null)
    fetchPosts({ pageSize: 1 })
      .then((res) => {
        if (cancelled) return
        setTypes(res.types)
        setLoading(false)
      })
      .catch((err: unknown) => {
        if (cancelled) return
        setError(err instanceof Error ? err.message : 'Failed to load Post Types')
        setLoading(false)
      })
    return () => {
      cancelled = true
    }
  }, [refreshToken])

  return (
    <div className="flex h-full flex-col gap-6 p-4 sm:p-6">
      <div className="flex flex-col gap-1">
        <h1 className="text-foreground text-xl font-medium tracking-tight sm:text-2xl">
          Post Types
        </h1>
        <p className="text-muted-foreground text-sm">
          Define content models and their fields. All types share the same default fields.
        </p>
      </div>

      {loading && <CardGridSkeleton />}
      {!loading && error && (
        <div className="border-border bg-card rounded-xl border p-8 text-center">
          <div className="text-foreground mb-2 text-sm font-medium">{error}</div>
          <button
            type="button"
            onClick={() => setRefreshToken((t) => t + 1)}
            className="text-primary text-sm hover:underline"
          >
            Try again
          </button>
        </div>
      )}

      {!loading && !error && (
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
          {types.map((t) => (
            <PostTypeCard
              key={t.slug}
              type={t}
              onClick={() => onNavigate(`/posts/types/${t.slug}/edit`)}
              onEditTemplate={() => onNavigate(`/posts/types/${t.slug}/template`)}
            />
          ))}
          <NewPostTypeCard onClick={() => onNavigate('/posts/types/new')} />
        </div>
      )}
    </div>
  )
}

// ─── PostTypeCard ────────────────────────────────────────────────────

function PostTypeCard({
  type,
  onClick,
  onEditTemplate,
}: {
  type: PostType
  onClick: () => void
  onEditTemplate: () => void
}) {
  const palette = paletteFor(type.accentColor)
  const Icon = resolvePostTypeIcon(type.icon)
  // Tailwind needs the exact class string at build time — derive the
  // top-border color from the palette's `border` token directly so it
  // stays in sync with the badge color.
  const topBorderClass = palette.border

  return (
    <div className="bg-card border-border relative flex flex-col gap-3 overflow-hidden rounded-xl border p-5 shadow-sm transition-shadow hover:shadow-md">
      <span aria-hidden className={`absolute inset-x-0 top-0 h-1 ${topBorderClass}`} />
      {/* Main click target: manage posts of this type. */}
      <button
        type="button"
        onClick={onClick}
        aria-label={`Manage ${type.name} posts`}
        className="focus-visible:ring-ring -m-1 flex flex-col gap-3 rounded-lg p-1 text-left focus:outline-none focus-visible:ring-2"
      >
        <div className="flex items-center gap-3 pt-2">
          <span
            className={`inline-flex h-9 w-9 items-center justify-center rounded-lg ${palette.bg} ${palette.text}`}
          >
            <Icon className="h-4 w-4" aria-hidden />
          </span>
          <h2 className="text-foreground text-base leading-tight font-medium">{type.name}</h2>
        </div>
        <p className="text-muted-foreground line-clamp-2 text-sm">
          {type.description ?? 'No description provided.'}
        </p>
      </button>
      <div className="border-border mt-auto flex flex-wrap items-center gap-x-4 gap-y-1 border-t pt-3 text-xs">
        <span className="text-foreground font-medium tabular-nums">
          {type.postCount} <span className="text-muted-foreground font-normal">posts</span>
        </span>
        <span className="text-foreground font-medium tabular-nums">
          {type.fieldCount} <span className="text-muted-foreground font-normal">fields</span>
        </span>
        <span className="text-muted-foreground ml-auto truncate font-mono">{type.urlBase}</span>
      </div>
      <button
        type="button"
        onClick={onEditTemplate}
        className="border-border text-foreground hover:bg-accent focus-visible:ring-ring inline-flex items-center justify-center gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs font-medium transition-colors focus:outline-none focus-visible:ring-2"
      >
        <LayoutTemplate className="h-3.5 w-3.5" aria-hidden />
        Edit template
      </button>
    </div>
  )
}

function NewPostTypeCard({ onClick }: { onClick: () => void }) {
  return (
    <button
      type="button"
      onClick={onClick}
      aria-label="New Post Type"
      className="border-border text-muted-foreground hover:text-foreground hover:border-primary/50 hover:bg-primary/5 focus-visible:ring-ring flex min-h-[170px] flex-col items-center justify-center gap-2 rounded-xl border-2 border-dashed bg-transparent p-5 transition-colors focus:outline-none focus-visible:ring-2"
    >
      <span className="bg-muted text-muted-foreground inline-flex h-9 w-9 items-center justify-center rounded-full">
        <Plus className="h-4 w-4" aria-hidden />
      </span>
      <span className="text-sm font-medium">New Post Type</span>
    </button>
  )
}

function CardGridSkeleton() {
  return (
    <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
      {Array.from({ length: 4 }).map((_, i) => (
        <div
          key={i}
          className="bg-card border-border min-h-[170px] animate-pulse rounded-xl border p-5"
        >
          <div className="bg-muted mb-3 h-9 w-9 rounded-lg" />
          <div className="bg-muted mb-2 h-4 w-1/2 rounded" />
          <div className="bg-muted h-3 w-3/4 rounded" />
        </div>
      ))}
    </div>
  )
}
