"use client";

import { FormEvent, useEffect, useMemo, useState } from "react";
import Image from "next/image";

type ShamePhoto = {
  name: string;
  path: string;
  url: string;
  htmlUrl: string;
};

type PhotoResponse = {
  photos: ShamePhoto[];
  repo: string | null;
  path: string;
  branch?: string | null;
  message: string | null;
};

const initialRepo = process.env.NEXT_PUBLIC_GITHUB_REPO ?? "";
const initialPath = process.env.NEXT_PUBLIC_GITHUB_PHOTOS_PATH ?? "";
const initialBranch = process.env.NEXT_PUBLIC_GITHUB_BRANCH ?? "";

function buildQuery(repo: string, path: string, branch: string) {
  const query = new URLSearchParams();

  if (repo.trim()) {
    query.set("repo", repo.trim());
  }

  if (path.trim()) {
    query.set("path", path.trim().replace(/^\/+/, ""));
  }

  if (branch.trim()) {
    query.set("branch", branch.trim());
  }

  return query.toString();
}

export default function Home() {
  const [repo, setRepo] = useState(initialRepo);
  const [path, setPath] = useState(initialPath);
  const [branch, setBranch] = useState(initialBranch);
  const [activeQuery, setActiveQuery] = useState(() => buildQuery(initialRepo, initialPath, initialBranch));
  const [data, setData] = useState<PhotoResponse | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const controller = new AbortController();

    async function loadPhotos() {
      setIsLoading(true);
      setError(null);

      try {
        const response = await fetch(`/api/github-photos?${activeQuery}`, {
          signal: controller.signal
        });
        const nextData = (await response.json()) as PhotoResponse;

        setData(nextData);

        if (!response.ok) {
          setError(nextData.message || "Could not load photos from GitHub.");
        }
      } catch (nextError) {
        if (nextError instanceof DOMException && nextError.name === "AbortError") {
          return;
        }

        setError("Could not reach the photo source.");
      } finally {
        setIsLoading(false);
      }
    }

    loadPhotos();

    return () => controller.abort();
  }, [activeQuery]);

  const repoLabel = data?.repo ?? "GitHub source not set";
  const boardStamp = useMemo(() => {
    const count = data?.photos.length ?? 0;

    if (count === 0) {
      return "Empty";
    }

    return `${count} filed`;
  }, [data?.photos.length]);

  function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setActiveQuery(buildQuery(repo, path, branch));
  }

  return (
    <main className="shell">
      <section className="hero" aria-labelledby="page-title">
        <div className="heroText">
          <h1 id="page-title">Доска позора</h1>
          <p className="summary">
            тут только самое позорное.
          </p>
        </div>
        <div className="caseTag" aria-label="Board status">
          <span>{boardStamp}</span>
          <strong>{repoLabel}</strong>
        </div>
      </section>

      <form className="sourceBar" onSubmit={handleSubmit}>
        <label>
          <span>repo</span>
          <input
            value={repo}
            onChange={(event) => setRepo(event.target.value)}
            spellCheck={false}
          />
        </label>
        <label>
          <span>folder</span>
          <input
            value={path}
            onChange={(event) => setPath(event.target.value)}
            spellCheck={false}
          />
        </label>
        <label>
          <span>branch</span>
          <input
            value={branch}
            onChange={(event) => setBranch(event.target.value)}
            spellCheck={false}
          />
        </label>
        <button type="submit">Обновить</button>
      </form>

      <section className="board" aria-live="polite" aria-busy={isLoading}>
        {isLoading ? <div className="notice">Загружаю фотографии с GitHub...</div> : null}
        {!isLoading && error ? <div className="notice danger">{error}</div> : null}
        {!isLoading && !error && data?.message ? <div className="notice">{data.message}</div> : null}

        {data?.photos.map((photo, index) => (
          <article className="photoCard" key={photo.path} style={{ "--tilt": `${(index % 5) - 2}deg` } as React.CSSProperties}>
            <a href={photo.htmlUrl} target="_blank" rel="noreferrer" aria-label={`Open ${photo.name} on GitHub`}>
              <Image src={photo.url} alt={photo.name} fill sizes="(max-width: 520px) 100vw, (max-width: 1200px) 33vw, 260px" />
            </a>
            <div className="caption">
              <span>#{String(index + 1).padStart(2, "0")}</span>
              <strong>{photo.name}</strong>
            </div>
          </article>
        ))}
      </section>
    </main>
  );
}
