import Link from "next/link";
import { notFound, redirect } from "next/navigation";
import {
  archiveProjectAction,
  deleteMediaAction,
  deleteProjectAction,
  publishProjectAction,
  setProjectHeroAction,
  updateMediaAltAction,
  updateProjectAction,
} from "@/app/dashboard/actions";
import { DashboardShell } from "@/components/dashboard/dashboard-shell";
import { requireDashboardContext } from "@/core/auth/dashboard-context";
import { getStorage } from "@/core/storage/storage";
import { listCategories } from "@/services/category-service";
import {
  getProjectForTenant,
  listProjectMedia,
} from "@/services/project-service";
import { ProjectMediaUploader } from "@/app/dashboard/projects/media-uploader";

export default async function ProjectDetailPage({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  const ctx = await requireDashboardContext("projects:view");
  const project = await getProjectForTenant(ctx.tenant, id);
  if (!project) notFound();

  const [media, categories] = await Promise.all([
    listProjectMedia(ctx.tenant, id),
    listCategories(ctx.tenant),
  ]);
  const storage = getStorage();
  const mediaWithUrls = await Promise.all(
    media.map(async (item) => ({
      item,
      url:
        item.fileType === "image"
          ? await storage.getSignedUrl(item.storageKey, ctx.tenant.tenantId)
          : null,
      isHero: project.heroStorageKey === item.storageKey,
    })),
  );

  async function save(formData: FormData) {
    "use server";
    const result = await updateProjectAction(id, formData);
    if (!result.ok) {
      redirect(`/dashboard/projects/${id}?error=1`);
    }
    redirect(`/dashboard/projects/${id}?saved=1`);
  }

  return (
    <DashboardShell>
      <Link
        href="/dashboard/projects"
        className="text-sm text-[var(--archi-ink-muted)]"
      >
        ← Projects
      </Link>
      <div className="mt-4 flex flex-wrap items-end justify-between gap-4">
        <div>
          <p className="text-xs uppercase tracking-[0.2em] text-[var(--archi-ink-muted)]">
            {project.status}
          </p>
          <h1 className="mt-1 font-[family-name:var(--font-display)] text-4xl">
            {project.title}
          </h1>
        </div>
        <div className="flex flex-wrap gap-2">
          {project.status !== "published" ? (
            <form action={publishProjectAction.bind(null, project.id)}>
              <button type="submit" className="archi-btn-primary">
                Publish
              </button>
            </form>
          ) : (
            <form action={archiveProjectAction.bind(null, project.id)}>
              <button
                type="submit"
                className="border border-[var(--archi-line)] bg-white px-4 py-2 text-sm"
              >
                Archive
              </button>
            </form>
          )}
          <form action={deleteProjectAction.bind(null, project.id)}>
            <button
              type="submit"
              className="border border-red-300 px-4 py-2 text-sm text-red-800"
            >
              Delete
            </button>
          </form>
        </div>
      </div>

      <form action={save} className="mt-10 space-y-4">
        <Field name="title" label="Title" defaultValue={project.title} required />
        <Field name="slug" label="Slug" defaultValue={project.slug} />
        <label className="block text-sm">
          Category
          <select
            name="categoryId"
            defaultValue={project.categoryId ?? ""}
            className="archi-input mt-2"
          >
            <option value="">Uncategorized</option>
            {categories.map((category) => (
              <option key={category.id} value={category.id}>
                {category.name}
              </option>
            ))}
          </select>
        </label>
        <Field
          name="location"
          label="Location"
          defaultValue={project.location ?? ""}
        />
        <Field
          name="year"
          label="Year"
          type="number"
          defaultValue={project.year?.toString() ?? ""}
        />
        <Field name="area" label="Area" defaultValue={project.area ?? ""} />
        <Field
          name="clientName"
          label="Client"
          defaultValue={project.clientName ?? ""}
        />
        <Field
          name="architectCredit"
          label="Architect credit"
          defaultValue={project.architectCredit ?? ""}
        />
        <Field
          name="projectType"
          label="Project type"
          defaultValue={project.projectType ?? ""}
        />
        <label className="block text-sm">
          Description
          <textarea
            name="description"
            rows={4}
            defaultValue={project.description ?? ""}
            className="archi-input mt-2"
          />
        </label>
        <label className="block text-sm">
          Concept
          <textarea
            name="concept"
            rows={4}
            defaultValue={project.concept ?? ""}
            className="archi-input mt-2"
          />
        </label>
        <label className="block text-sm">
          Design process
          <textarea
            name="designProcess"
            rows={4}
            defaultValue={project.designProcess ?? ""}
            className="archi-input mt-2"
          />
        </label>
        <label className="block text-sm">
          Materials
          <textarea
            name="materials"
            rows={3}
            defaultValue={project.materials ?? ""}
            className="archi-input mt-2"
          />
        </label>
        <Field
          name="videoUrl"
          label="Video URL"
          defaultValue={project.videoUrl ?? ""}
        />
        <label className="flex items-center gap-2 text-sm">
          <input
            name="isFeatured3d"
            type="checkbox"
            defaultChecked={project.isFeatured3d}
          />
          Feature on 3D Experience page
        </label>
        <Field
          name="seoTitle"
          label="SEO title"
          defaultValue={project.seoTitle ?? ""}
        />
        <label className="block text-sm">
          SEO description
          <textarea
            name="seoDescription"
            rows={2}
            defaultValue={project.seoDescription ?? ""}
            className="archi-input mt-2"
          />
        </label>
        <button type="submit" className="archi-btn-primary">
          Save changes
        </button>
      </form>

      <section className="mt-14">
        <h2 className="font-[family-name:var(--font-display)] text-2xl">
          Media
        </h2>
        <p className="mt-2 text-sm text-[var(--archi-ink-muted)]">
          Upload images, set a hero for list cards, and manage alt text.
        </p>
        <div className="mt-6">
          <ProjectMediaUploader projectId={project.id} />
        </div>
        {mediaWithUrls.length === 0 ? (
          <p className="mt-6 text-sm text-[var(--archi-ink-muted)]">
            No media attached yet.
          </p>
        ) : (
          <ul className="mt-6 grid gap-4 sm:grid-cols-2">
            {mediaWithUrls.map(({ item, url, isHero }) => (
              <li
                key={item.id}
                className="overflow-hidden border border-[var(--archi-line)] bg-white/70"
              >
                <div className="relative aspect-[16/10] bg-[var(--archi-bg-deep)]">
                  {url ? (
                    // eslint-disable-next-line @next/next/no-img-element
                    <img src={url} alt={item.altText ?? ""} className="h-full w-full object-cover" />
                  ) : (
                    <div className="flex h-full items-center justify-center text-xs text-[var(--archi-ink-muted)]">
                      {item.fileType}
                    </div>
                  )}
                  {isHero ? (
                    <span className="absolute top-2 left-2 bg-[var(--archi-gold)] px-2 py-0.5 text-[10px] font-bold text-[var(--archi-dark)] uppercase">
                      Hero
                    </span>
                  ) : null}
                </div>
                <div className="space-y-2 p-3 text-sm">
                  <p className="truncate font-medium">
                    {item.storageKey.split("/").pop()}
                  </p>
                  <p className="text-xs text-[var(--archi-ink-muted)]">
                    {item.mimeType} · {(item.fileSize / 1024).toFixed(0)} KB
                  </p>
                  <form
                    action={async (formData) => {
                      "use server";
                      await updateMediaAltAction(item.id, formData);
                    }}
                    className="flex gap-2"
                  >
                    <input
                      name="altText"
                      defaultValue={item.altText ?? ""}
                      placeholder="Alt text"
                      className="min-w-0 flex-1 border border-[var(--archi-line)] px-2 py-1 text-xs"
                    />
                    <button type="submit" className="text-xs underline">
                      Save
                    </button>
                  </form>
                  <div className="flex flex-wrap gap-2">
                    {item.fileType === "image" && !isHero ? (
                      <form
                        action={setProjectHeroAction.bind(null, project.id, item.id)}
                      >
                        <button type="submit" className="text-xs underline">
                          Set as hero
                        </button>
                      </form>
                    ) : null}
                    <form action={deleteMediaAction.bind(null, item.id)}>
                      <button
                        type="submit"
                        className="text-xs text-red-800 underline"
                      >
                        Delete
                      </button>
                    </form>
                  </div>
                </div>
              </li>
            ))}
          </ul>
        )}
      </section>
    </DashboardShell>
  );
}

function Field({
  name,
  label,
  required,
  type = "text",
  defaultValue,
}: {
  name: string;
  label: string;
  required?: boolean;
  type?: string;
  defaultValue?: string;
}) {
  return (
    <label className="block text-sm">
      {label}
      <input
        name={name}
        type={type}
        required={required}
        defaultValue={defaultValue}
        className="archi-input mt-2"
      />
    </label>
  );
}
