import {
  attachArtworkRendition,
  createAlbum,
  createArtwork,
  createCategory,
  createGallery,
  createTag,
  linkArtworkToGrouping,
  listArtworks,
  listMediaAssets,
  listMediaFoundationGroups,
} from "@cms/db"
import { Button } from "@cms/ui/button"
import { revalidatePath } from "next/cache"
import { redirect } from "next/navigation"

import { AdminShell } from "@/components/admin-shell"
import { requirePermissionForRoute } from "@/lib/route-guards"

export const dynamic = "force-dynamic"

type SearchParamsInput = Record<string, string | string[] | undefined>
type GroupType = "gallery" | "album" | "category" | "tag"

function readField(formData: FormData, key: string): string {
  const value = formData.get(key)
  return typeof value === "string" ? value.trim() : ""
}

function readOptionalField(formData: FormData, key: string): string | undefined {
  const value = readField(formData, key)
  return value.length > 0 ? value : undefined
}

function readFirstValue(value: string | string[] | undefined): string | null {
  if (Array.isArray(value)) {
    return value[0] ?? null
  }

  return value ?? null
}

function slugify(input: string): string {
  return input
    .toLowerCase()
    .trim()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "")
    .slice(0, 180)
}

function redirectWithState(params: { notice?: string; error?: string }) {
  const query = new URLSearchParams()

  if (params.notice) {
    query.set("notice", params.notice)
  }

  if (params.error) {
    query.set("error", params.error)
  }

  const value = query.toString()
  redirect(value ? `/portfolio?${value}` : "/portfolio")
}

async function requireWritePermission() {
  await requirePermissionForRoute({
    nextPath: "/portfolio",
    permission: "media:write",
    scope: "team",
  })
}

async function createArtworkAction(formData: FormData) {
  "use server"

  await requireWritePermission()

  const title = readField(formData, "title")
  const slug = slugify(readField(formData, "slug") || title)

  try {
    await createArtwork({
      title,
      slug,
      description: readOptionalField(formData, "description"),
      medium: readOptionalField(formData, "medium"),
      dimensions: readOptionalField(formData, "dimensions"),
      framing: readOptionalField(formData, "framing"),
      availability: readOptionalField(formData, "availability"),
      year: (() => {
        const raw = readField(formData, "year")
        return raw ? Number(raw) : undefined
      })(),
    })
  } catch {
    redirectWithState({ error: "Failed to create artwork." })
  }

  revalidatePath("/portfolio")
  redirectWithState({ notice: "Artwork created." })
}

async function createGroupAction(formData: FormData) {
  "use server"

  await requireWritePermission()

  const type = readField(formData, "groupType") as GroupType
  const name = readField(formData, "name")
  const slug = slugify(readField(formData, "slug") || name)

  try {
    if (type === "gallery") {
      await createGallery({
        name,
        slug,
        description: readOptionalField(formData, "description"),
      })
    } else if (type === "album") {
      await createAlbum({
        name,
        slug,
        description: readOptionalField(formData, "description"),
      })
    } else if (type === "category") {
      await createCategory({
        name,
        slug,
        description: readOptionalField(formData, "description"),
      })
    } else {
      await createTag({
        name,
        slug,
      })
    }
  } catch {
    redirectWithState({ error: "Failed to create grouping entity." })
  }

  revalidatePath("/portfolio")
  redirectWithState({ notice: `${type} created.` })
}

async function linkArtworkGroupAction(formData: FormData) {
  "use server"

  await requireWritePermission()

  const artworkId = readField(formData, "artworkId")
  const groupType = readField(formData, "groupType") as GroupType
  const groupId = readField(formData, "groupId")

  try {
    await linkArtworkToGrouping({
      artworkId,
      groupType,
      groupId,
    })
  } catch {
    redirectWithState({ error: "Failed to link artwork to grouping." })
  }

  revalidatePath("/portfolio")
  redirectWithState({ notice: "Artwork linked to grouping." })
}

async function attachRenditionAction(formData: FormData) {
  "use server"

  await requireWritePermission()

  try {
    await attachArtworkRendition({
      artworkId: readField(formData, "artworkId"),
      mediaAssetId: readField(formData, "mediaAssetId"),
      slot: readField(formData, "slot"),
      width: (() => {
        const raw = readField(formData, "width")
        return raw ? Number(raw) : undefined
      })(),
      height: (() => {
        const raw = readField(formData, "height")
        return raw ? Number(raw) : undefined
      })(),
      isPrimary: readField(formData, "isPrimary") === "true",
    })
  } catch {
    redirectWithState({ error: "Failed to attach artwork rendition." })
  }

  revalidatePath("/portfolio")
  redirectWithState({ notice: "Rendition attached." })
}

export default async function PortfolioPage({
  searchParams,
}: {
  searchParams: Promise<SearchParamsInput>
}) {
  const role = await requirePermissionForRoute({
    nextPath: "/portfolio",
    permission: "media:read",
    scope: "team",
  })
  const [resolvedSearchParams, artworks, mediaAssets, groups] = await Promise.all([
    searchParams,
    listArtworks(30),
    listMediaAssets(200),
    listMediaFoundationGroups(),
  ])
  const notice = readFirstValue(resolvedSearchParams.notice)
  const error = readFirstValue(resolvedSearchParams.error)

  return (
    <AdminShell
      role={role}
      activePath="/portfolio"
      badge="Admin App"
      title="Portfolio"
      description="Artwork foundation with rendition slots and grouping relations."
    >
      {notice ? (
        <section className="rounded-xl border border-emerald-300 bg-emerald-50 px-4 py-3 text-sm text-emerald-800">
          {notice}
        </section>
      ) : null}

      {error ? (
        <section className="rounded-xl border border-red-300 bg-red-50 px-4 py-3 text-sm text-red-800">
          {error}
        </section>
      ) : null}

      <section className="rounded-xl border border-neutral-200 p-6">
        <h2 className="text-xl font-medium">Create Artwork</h2>
        <form action={createArtworkAction} className="mt-4 space-y-3">
          <div className="grid gap-3 md:grid-cols-2">
            <label className="space-y-1">
              <span className="text-xs text-neutral-600">Title</span>
              <input
                name="title"
                required
                className="w-full rounded border border-neutral-300 px-3 py-2 text-sm"
              />
            </label>
            <label className="space-y-1">
              <span className="text-xs text-neutral-600">Slug (optional)</span>
              <input
                name="slug"
                className="w-full rounded border border-neutral-300 px-3 py-2 text-sm"
              />
            </label>
          </div>
          <label className="space-y-1">
            <span className="text-xs text-neutral-600">Description</span>
            <textarea
              name="description"
              rows={3}
              className="w-full rounded border border-neutral-300 px-3 py-2 text-sm"
            />
          </label>
          <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
            <input
              name="medium"
              placeholder="Medium"
              className="rounded border border-neutral-300 px-3 py-2 text-sm"
            />
            <input
              name="dimensions"
              placeholder="Dimensions"
              className="rounded border border-neutral-300 px-3 py-2 text-sm"
            />
            <input
              name="year"
              type="number"
              placeholder="Year"
              className="rounded border border-neutral-300 px-3 py-2 text-sm"
            />
            <input
              name="framing"
              placeholder="Framing"
              className="rounded border border-neutral-300 px-3 py-2 text-sm"
            />
          </div>
          <input
            name="availability"
            placeholder="Availability"
            className="w-full rounded border border-neutral-300 px-3 py-2 text-sm"
          />
          <Button type="submit">Create artwork</Button>
        </form>
      </section>

      <section className="rounded-xl border border-neutral-200 p-6">
        <h2 className="text-xl font-medium">Create Group Entity</h2>
        <form action={createGroupAction} className="mt-4 space-y-3">
          <div className="grid gap-3 md:grid-cols-3">
            <select
              name="groupType"
              defaultValue="gallery"
              className="rounded border border-neutral-300 px-3 py-2 text-sm"
            >
              <option value="gallery">gallery</option>
              <option value="album">album</option>
              <option value="category">category</option>
              <option value="tag">tag</option>
            </select>
            <input
              name="name"
              required
              placeholder="Name"
              className="rounded border border-neutral-300 px-3 py-2 text-sm"
            />
            <input
              name="slug"
              placeholder="Slug (optional)"
              className="rounded border border-neutral-300 px-3 py-2 text-sm"
            />
          </div>
          <textarea
            name="description"
            rows={2}
            placeholder="Description (optional)"
            className="w-full rounded border border-neutral-300 px-3 py-2 text-sm"
          />
          <Button type="submit">Create group</Button>
        </form>
      </section>

      <section className="rounded-xl border border-neutral-200 p-6">
        <h2 className="text-xl font-medium">Link Artwork To Group</h2>
        <div className="mt-4 grid gap-4 lg:grid-cols-2">
          {(
            [
              { type: "gallery" as const, label: "Gallery", items: groups.galleries },
              { type: "album" as const, label: "Album", items: groups.albums },
              { type: "category" as const, label: "Category", items: groups.categories },
              { type: "tag" as const, label: "Tag", items: groups.tags },
            ] as const
          ).map((groupConfig) => (
            <form
              key={groupConfig.type}
              action={linkArtworkGroupAction}
              className="space-y-3 rounded border border-neutral-200 p-4"
            >
              <h3 className="text-sm font-semibold">{groupConfig.label} Link</h3>
              <input type="hidden" name="groupType" value={groupConfig.type} />
              <select
                name="artworkId"
                className="w-full rounded border border-neutral-300 px-3 py-2 text-sm"
              >
                {artworks.map((artwork) => (
                  <option key={`${groupConfig.type}-${artwork.id}`} value={artwork.id}>
                    {artwork.title}
                  </option>
                ))}
              </select>
              <select
                name="groupId"
                className="w-full rounded border border-neutral-300 px-3 py-2 text-sm"
              >
                {groupConfig.items.map((group) => (
                  <option key={`${groupConfig.type}-${group.id}`} value={group.id}>
                    {group.name}
                  </option>
                ))}
              </select>
              <Button type="submit">Link artwork</Button>
            </form>
          ))}
        </div>
      </section>

      <section className="rounded-xl border border-neutral-200 p-6">
        <h2 className="text-xl font-medium">Attach Artwork Rendition Slot</h2>
        <form
          action={attachRenditionAction}
          className="mt-4 grid gap-3 md:grid-cols-3 xl:grid-cols-6"
        >
          <select name="artworkId" className="rounded border border-neutral-300 px-3 py-2 text-sm">
            {artworks.map((artwork) => (
              <option key={artwork.id} value={artwork.id}>
                {artwork.title}
              </option>
            ))}
          </select>
          <select
            name="mediaAssetId"
            className="rounded border border-neutral-300 px-3 py-2 text-sm"
          >
            {mediaAssets.map((asset) => (
              <option key={asset.id} value={asset.id}>
                {asset.title}
              </option>
            ))}
          </select>
          <select
            name="slot"
            defaultValue="thumbnail"
            className="rounded border border-neutral-300 px-3 py-2 text-sm"
          >
            <option value="thumbnail">thumbnail</option>
            <option value="card">card</option>
            <option value="full">full</option>
            <option value="custom">custom</option>
          </select>
          <input
            name="width"
            type="number"
            placeholder="width"
            className="rounded border border-neutral-300 px-3 py-2 text-sm"
          />
          <input
            name="height"
            type="number"
            placeholder="height"
            className="rounded border border-neutral-300 px-3 py-2 text-sm"
          />
          <select
            name="isPrimary"
            defaultValue="false"
            className="rounded border border-neutral-300 px-3 py-2 text-sm"
          >
            <option value="false">not primary</option>
            <option value="true">primary</option>
          </select>
          <div className="md:col-span-3 xl:col-span-6">
            <Button type="submit">Attach rendition</Button>
          </div>
        </form>
      </section>

      <section className="rounded-xl border border-neutral-200 p-6">
        <div className="flex items-center justify-between gap-2">
          <h2 className="text-xl font-medium">Artworks</h2>
          <span className="text-xs uppercase tracking-[0.2em] text-neutral-500">
            MVP1 Foundation
          </span>
        </div>
        <div className="mt-4 overflow-x-auto">
          <table className="min-w-full text-left text-sm">
            <thead className="text-xs uppercase tracking-wide text-neutral-500">
              <tr>
                <th className="py-2 pr-4">Title</th>
                <th className="py-2 pr-4">Slug</th>
                <th className="py-2 pr-4">Published</th>
                <th className="py-2 pr-4">Renditions</th>
                <th className="py-2 pr-4">Groups</th>
              </tr>
            </thead>
            <tbody>
              {artworks.length === 0 ? (
                <tr>
                  <td className="py-3 text-neutral-500" colSpan={5}>
                    No artworks yet. Add creation flows after media upload pipeline lands.
                  </td>
                </tr>
              ) : (
                artworks.map((artwork) => (
                  <tr key={artwork.id} className="border-t border-neutral-200">
                    <td className="py-3 pr-4">{artwork.title}</td>
                    <td className="py-3 pr-4 font-mono text-xs">{artwork.slug}</td>
                    <td className="py-3 pr-4">{artwork.isPublished ? "yes" : "no"}</td>
                    <td className="py-3 pr-4">{artwork.renditions.length}</td>
                    <td className="py-3 pr-4 text-neutral-600">
                      g:{artwork.galleryLinks.length} a:{artwork.albumLinks.length} c:
                      {artwork.categoryLinks.length} t:{artwork.tagLinks.length}
                    </td>
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </div>
      </section>
    </AdminShell>
  )
}
