import Link from "next/link";
import { Star, Calendar, Clock, Building2, Film, Tag as TagIcon, Captions } from "lucide-react";
import { CoverFlagToggle } from "./CoverFlagToggle";
import { getImageDetail, listAllCollections, listAttachedImages, listAllActresses, listAllGenres } from "@/lib/db/queries";
import { CoverEditor } from "@/components/cover/CoverEditor";
import { CoverPlayButton } from "@/components/video/CoverPlayButton";
import { TagEditor } from "@/components/tags/TagEditor";
import { CollectionPicker } from "@/components/collections/CollectionPicker";
import { AttachedImages } from "@/components/image/AttachedImages";
import { formatBytes } from "@/lib/utils";
import { imageUrl } from "@/lib/assetUrls";
import { formatBitrate, formatDuration, formatResolution, formatBytes as formatVideoBytes, formatVideoSummary, listStoredVideoMetadataForCode } from "@/lib/video/metadata";
import { Panel, PanelStack, PanelSection, PanelHeader, ChipCluster } from "@/components/ui/panel";
import path from "node:path";

export function ImageDetailView({ imageId }: { imageId: number }) {
  const detail = getImageDetail(imageId);
  if (!detail) return null;
  const allCollections = listAllCollections().map((c) => ({ id: c.id, name: c.name, slug: c.slug }));
  const attached = listAttachedImages(detail.image.id);
  const actressSuggestions = listAllActresses().map((a) => {
    const primaryAliases: string[] = [];
    const tokens = a.name.trim().split(/\s+/).filter(Boolean);
    if (tokens.length >= 2) primaryAliases.push(tokens.slice().reverse().join(" "));
    const aliases: string[] = [];
    if (a.altNames) {
      for (const part of a.altNames.split(/[,、，]/)) {
        const t = part.trim();
        if (t) aliases.push(t);
      }
    }
    return { name: a.name, primaryAliases, aliases };
  });
  const genreSuggestions = listAllGenres().map((g) => g.name);
  const { image, studio, label, series, actresses, genres, tags, collections } = detail;
  const videoMetas = image.hasVideo ? listStoredVideoMetadataForCode(image.code) : [];
  const videoSummary = videoMetas.map((meta) => formatVideoSummary(meta)).find(Boolean);
  // Pull the first probed-clean meta for the per-stat hero strip. Falls
  // back to the very first row if none have a usable probe yet.
  const heroMeta = videoMetas.find((m) => !m.probeError) ?? videoMetas[0] ?? null;
  const heroStats = heroMeta && !heroMeta.probeError
    ? {
        resolution: formatResolution(heroMeta.width, heroMeta.height),
        bitrate: formatBitrate(heroMeta.videoBitrate),
        // Sum across parts so the user sees the actual disk footprint
        // for the whole title, not just the first file.
        size: formatVideoBytes(videoMetas.reduce((acc, m) => acc + (m.sizeBytes ?? 0), 0)),
        // Same for length — total runtime across all parts.
        length: formatDuration(videoMetas.reduce((acc, m) => acc + (m.durationSec ?? 0), 0)),
      }
    : null;

  return (
    <div key={image.id} className="pb-12 fade-in">
      <div className="grid grid-cols-1 lg:grid-cols-[800px_minmax(0,1fr)] gap-6">
        <div>
          <div className="glass rounded-2xl overflow-hidden relative">
            {/* eslint-disable-next-line @next/next/no-img-element */}
            <img
              src={imageUrl({ id: image.id, code: image.code, ext: path.extname(image.filename), v: image.sha256.slice(0, 12) })}
              alt={image.title ?? image.code ?? image.filename}
              width={image.width}
              height={image.height}
              className="block w-full h-auto max-w-[800px] max-h-[538px]"
            />
            <CoverPlayButton
              code={image.code}
              actresses={actresses.map((a) => ({ id: a.id, name: a.name, slug: a.slug }))}
            />
          </div>
          <AttachedImages parentId={image.id} items={attached} />
        </div>

        <PanelStack as="aside">
          <Panel>
          <PanelSection>
            <div className="flex items-start justify-between gap-3">
              <div className="min-w-0 space-y-1.5 flex-1">
                <div className="flex items-center justify-between gap-3">
                  {image.code ? (
                    <div className="flex items-center gap-2">
                      <span className="text-base uppercase tracking-wider font-mono font-semibold text-[var(--color-cyan)]">
                        {image.code}
                      </span>
                      {image.hasSubtitle && (
                        <span
                          title="Subtitle file available"
                          className="inline-flex items-center gap-1 text-[10px] uppercase tracking-wider font-mono px-1.5 py-0.5 rounded border border-[var(--color-mint)]/40 bg-[var(--color-mint)]/10 text-[var(--color-mint)]"
                        >
                          <Captions className="w-3 h-3" /> CC
                        </span>
                      )}
                    </div>
                  ) : (
                    <div />
                  )}
                  {image.rating != null && (
                    <div className="flex items-center gap-0.5 shrink-0">
                      {Array.from({ length: 5 }).map((_, i) => (
                        <Star
                          key={i}
                          className={`w-3.5 h-3.5 ${i < image.rating! ? "fill-[var(--color-cyan)] text-[var(--color-cyan)]" : "text-[var(--color-fg-muted)]"}`}
                        />
                      ))}
                    </div>
                  )}
                </div>
                <h1 className="text-lg font-medium truncate" title={image.title ?? image.filename}>
                  {image.title || <span className="text-[var(--color-fg-muted)] italic">Untitled</span>}
                </h1>
              </div>
            </div>

            <div className="grid grid-cols-4 gap-chip text-xs w-full">
              <CoverFlagToggle kind="vip" imageId={image.id} initial={image.isVip} />
              <CoverFlagToggle kind="favorite" imageId={image.id} initial={image.isFavorite} />
              <CoverFlagToggle kind="watched" imageId={image.id} initial={image.watched} />
              <CoverFlagToggle kind="owned" imageId={image.id} initial={image.isOwned} />
            </div>

            {(image.releaseDate || image.runtimeMin || image.director) && (
              <div className="grid grid-cols-3 gap-chip text-xs font-mono text-[var(--color-fg-dim)] pt-section border-t border-[var(--color-glass-border)]">
                {image.releaseDate && <Field icon={Calendar} label="Released" value={image.releaseDate} />}
                {image.runtimeMin != null && <Field icon={Clock} label="Runtime" value={`${image.runtimeMin} min`} />}
                {image.director && <Field label="Director" value={image.director} />}
              </div>
            )}

            <div className="flex flex-wrap items-baseline justify-center gap-x-5 gap-y-1 text-[12px] font-mono text-[var(--color-fg-muted)] pt-section border-t border-[var(--color-glass-border)]">
              <InlineMeta label="Resolution" value={`${image.width}×${image.height}`} />
              <span className="opacity-30">·</span>
              <InlineMeta label="Size" value={formatBytes(image.bytes)} />
              <span className="opacity-30">·</span>
              <InlineMeta label="Imported" value={new Date(image.importedAt).toLocaleDateString()} />
            </div>
            {heroStats && (
              <div className="grid grid-cols-4 gap-stat-gap text-center pt-section border-t border-[var(--color-glass-border)]">
                {heroStats.resolution && (
                  <HeroStat label="Resolution" value={heroStats.resolution} />
                )}
                {heroStats.bitrate && (
                  <HeroStat label="Bitrate" value={heroStats.bitrate} />
                )}
                {heroStats.size && (
                  <HeroStat label="File Size" value={heroStats.size} accent />
                )}
                {heroStats.length && (
                  <HeroStat label="Length" value={heroStats.length} cyan />
                )}
              </div>
            )}
            {/* Video summary is suppressed when heroStats render — the 4-up
                strip already covers resolution/bitrate/size/length. Falls
                back to the inline summary on rows where the probe didn't
                yield enough data for the hero strip. */}
            {!heroStats && videoSummary && (
              <div className="text-[13px] font-mono text-[var(--color-fg-muted)]">
                <InlineMeta label={videoMetas.length > 1 ? `Video (${videoMetas.length} parts)` : "Video"} value={videoSummary} />
              </div>
            )}
          </PanelSection>
          </Panel>

          {(studio || label || series) && (
            <Panel className="flex flex-col gap-chip">
              {studio && <EntityLink icon={Building2} href={`/studios/${studio.slug}`} label="Studio" name={studio.name} />}
              {label && <EntityLink icon={TagIcon} href={`/labels/${label.slug}`} label="Label" name={label.name} />}
              {series && <EntityLink icon={Film} href={`/series/${series.slug}`} label="Series" name={series.name} />}
            </Panel>
          )}

          {actresses.length > 0 && (
            <Section title="Actresses">
              <ChipCluster>
                {actresses.map((a) => (
                  <Link
                    key={a.id}
                    href={`/actress/${a.slug}`}
                    className="px-2.5 py-1 rounded-full text-xs border transition-colors"
                    style={{
                      background: "color-mix(in oklch, var(--color-violet) 14%, transparent)",
                      color: "var(--color-violet)",
                      borderColor: "color-mix(in oklch, var(--color-violet) 35%, transparent)",
                    }}
                  >
                    {a.name}
                  </Link>
                ))}
              </ChipCluster>
            </Section>
          )}

          {genres.length > 0 && (
            <Section title="Genres">
              <ChipCluster>
                {genres.map((g) => (
                  <Link
                    key={g.id}
                    href={`/genres/${g.slug}`}
                    className="px-2.5 py-1 rounded-full text-xs border transition-colors"
                    style={{
                      background: "color-mix(in oklch, var(--color-cyan) 14%, transparent)",
                      color: "var(--color-cyan)",
                      borderColor: "color-mix(in oklch, var(--color-cyan) 35%, transparent)",
                    }}
                  >
                    {g.name}
                  </Link>
                ))}
              </ChipCluster>
            </Section>
          )}

          <Panel>
            <TagEditor imageId={image.id} initial={tags} />
          </Panel>
          <Panel>
            <CollectionPicker imageId={image.id} current={collections} available={allCollections} />
          </Panel>

          <CoverEditor
            initial={{
              imageId: image.id,
              code: image.code,
              title: image.title,
              releaseDate: image.releaseDate,
              runtimeMin: image.runtimeMin,
              director: image.director,
              studio: studio?.name ?? null,
              label: label?.name ?? null,
              series: series?.name ?? null,
              rating: image.rating,
              watched: image.watched,
              notes: image.notes,
              actresses: actresses.map((a) => a.name),
              genres: genres.map((g) => g.name),
            }}
            actressSuggestions={actressSuggestions}
            genreSuggestions={genreSuggestions}
          />

          {image.notes && (
            <Panel>
              <PanelHeader>Notes</PanelHeader>
              <p className="text-sm whitespace-pre-wrap leading-relaxed">{image.notes}</p>
            </Panel>
          )}
        </PanelStack>
      </div>

    </div>
  );
}

function HeroStat({
  label,
  value,
  accent = false,
  cyan = false,
}: {
  label: string;
  value: string;
  /** Render the value in the brighter primary fg (used for headline stats). */
  accent?: boolean;
  /** Tint the value cyan — reserved for the single most-prominent stat. */
  cyan?: boolean;
}) {
  return (
    <div>
      <div className="text-[10px] uppercase tracking-wider font-mono text-[var(--color-fg-muted)] mb-stat">
        {label}
      </div>
      <div
        className={
          cyan
            ? "font-mono text-3xl font-semibold tracking-tight leading-none text-[var(--color-cyan)]"
            : accent
              ? "font-mono text-3xl font-semibold tracking-tight leading-none text-[var(--color-fg)]"
              : "font-mono text-2xl font-semibold tracking-tight leading-none text-[var(--color-fg-dim)]"
        }
      >
        {value}
      </div>
    </div>
  );
}

function InlineMeta({ label, value }: { label: string; value: string }) {
  return (
    <span className="inline-flex items-baseline gap-1.5">
      <span className="text-[10px] uppercase tracking-wider opacity-70">{label}</span>
      <span className="text-[var(--color-fg)]">{value}</span>
    </span>
  );
}

function Field({ icon: Icon, label, value }: { icon?: React.ComponentType<{ className?: string }>; label: string; value: string }) {
  return (
    <div>
      <div className="text-[9px] uppercase tracking-wider text-[var(--color-fg-muted)] flex items-center gap-1">
        {Icon && <Icon className="w-3 h-3" />}
        {label}
      </div>
      <div className="text-[var(--color-fg)] truncate">{value}</div>
    </div>
  );
}

function Section({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <Panel>
      <PanelHeader>{title}</PanelHeader>
      {children}
    </Panel>
  );
}

function EntityLink({ icon: Icon, href, label, name }: { icon: React.ComponentType<{ className?: string }>; href: string; label: string; name: string }) {
  return (
    <Link href={href} className="flex items-center gap-2 text-sm group">
      <Icon className="w-4 h-4 text-[var(--color-fg-muted)] group-hover:text-[var(--color-cyan)]" />
      <span className="text-[10px] uppercase tracking-wider font-mono text-[var(--color-fg-muted)] w-16">{label}</span>
      <span className="text-[var(--color-fg)] group-hover:text-[var(--color-cyan)]">{name}</span>
    </Link>
  );
}
