'use client';

import { useEffect, useMemo, useState } from 'react';
import { getRepos } from '@/lib/gitea';
import type { GiteaRepo } from '@/lib/types';
import { GITEA_URL, GITEA_USERNAME } from '@/lib/config';

const LANG_COLOR: Record<string, string> = {
  python: '#3572A5',
  javascript: '#f1e05a',
  typescript: '#3178c6',
  go: '#00add8',
  rust: '#dea584',
  'c++': '#f34b7d',
  c: '#555',
  html: '#e34c26',
  css: '#563d7c',
  shell: '#89e051',
  ruby: '#701516',
  java: '#b07219',
};

function langColor(l: string | null) {
  return LANG_COLOR[(l || '').toLowerCase()] || '#555';
}

function timeAgo(d: string | undefined | null) {
  if (!d) return '';
  const t = new Date(d).getTime();
  if (Number.isNaN(t)) return '';
  const diff = Date.now() - t;
  if (diff < 0) return 'just now';
  const m = Math.floor(diff / 60000);
  if (m < 1) return 'just now';
  if (m < 60) return `${m}m ago`;
  const h = Math.floor(m / 60);
  if (h < 24) return `${h}h ago`;
  const days = Math.floor(h / 24);
  if (days < 30) return `${days}d ago`;
  const months = Math.floor(days / 30);
  return `${months}mo ago`;
}

type SortKey = 'recent' | 'stars';

export default function Projects() {
  const [repos, setRepos] = useState<GiteaRepo[] | null>(null);
  const [error, setError] = useState<string | null>(null);

  const [activeRepo, setActiveRepo] = useState<GiteaRepo | null>(null);
  const [readmeHtml, setReadmeHtml] = useState<string | null>(null);
  const [readmeLoading, setReadmeLoading] = useState(false);
  const [readmeError, setReadmeError] = useState<string | null>(null);

  const [sortBy, setSortBy] = useState<SortKey>('recent');
  const [languageFilter, setLanguageFilter] = useState<string>('all');

  useEffect(() => {
    // Get all repos (or a high limit) instead of SITE.repoLimit
    getRepos(100)
      .then(setRepos)
      .catch(e => setError(e instanceof Error ? e.message : String(e)));
  }, []);

  // Load README when a repo is opened
  useEffect(() => {
    if (!activeRepo) return;
    setReadmeLoading(true);
    setReadmeError(null);
    setReadmeHtml(null);

    fetch(`/api/gitea/readme?repo=${encodeURIComponent(activeRepo.name)}`)
      .then(res => {
        if (!res.ok) throw new Error(`README HTTP ${res.status}`);
        return res.text();
      })
      .then(html => setReadmeHtml(html))
      .catch(e =>
        setReadmeError(
          e instanceof Error ? e.message : 'Could not load README',
        ),
      )
      .finally(() => setReadmeLoading(false));
  }, [activeRepo]);

  // Derive list of languages for filter
  const languages = useMemo(() => {
    if (!repos) return [];
    const set = new Set<string>();
    repos.forEach(r => {
      if (r.language) set.add(r.language);
    });
    return Array.from(set).sort((a, b) => a.localeCompare(b));
  }, [repos]);

  // Apply sort + language filter
  const filteredRepos = useMemo(() => {
    if (!repos) return null;
    let list = [...repos];

    if (languageFilter !== 'all') {
      list = list.filter(
        r => (r.language || '').toLowerCase() === languageFilter.toLowerCase(),
      );
    }

    list.sort((a, b) => {
      if (sortBy === 'stars') {
        return b.stars_count - a.stars_count;
      }
      // recent: sort by updated/updated_at desc
      const ad = new Date((a.updated || (a as any).updated_at) ?? '').getTime();
      const bd = new Date((b.updated || (b as any).updated_at) ?? '').getTime();
      return bd - ad;
    });

    return list;
  }, [repos, sortBy, languageFilter]);

  return (
    <section
      id="projects"
      className="py-24 px-6"
      aria-labelledby="projects-heading"
    >
      <div className="max-w-5xl mx-auto">
        <div className="flex flex-col sm:flex-row sm:items-end sm:justify-between gap-4 mb-8">
          <div>
            <h2
              id="projects-heading"
              className="text-[clamp(1.8rem,4vw,2.5rem)] font-black tracking-tight text-white"
            >
              Projects
            </h2>
            <p className="text-xs text-white/40 mt-1">
              Open-source work, sorted by activity or stars.
            </p>
          </div>
          <div className="flex flex-wrap items-center gap-3 text-xs">
            {/* Sort */}
            <div className="flex items-center gap-1.5">
              <span className="text-white/35">Sort:</span>
              <button
                type="button"
                onClick={() => setSortBy('recent')}
                className={`px-2.5 py-1 rounded-full border text-xs ${
                  sortBy === 'recent'
                    ? 'border-white/40 bg-white/10 text-white'
                    : 'border-white/10 text-white/40 hover:border-white/25 hover:text-white/70'
                }`}
              >
                Most recent
              </button>
              <button
                type="button"
                onClick={() => setSortBy('stars')}
                className={`px-2.5 py-1 rounded-full border text-xs ${
                  sortBy === 'stars'
                    ? 'border-white/40 bg-white/10 text-white'
                    : 'border-white/10 text-white/40 hover:border-white/25 hover:text-white/70'
                }`}
              >
                Stars
              </button>
            </div>
            {/* Language filter */}
            <div className="flex items-center gap-1.5">
              <span className="text-white/35">Language:</span>
              <select
                value={languageFilter}
                onChange={e => setLanguageFilter(e.target.value)}
                className="bg-white/5 border border-white/15 rounded-full px-2.5 py-1 text-xs text-white/80 focus:outline-none focus:ring-1 focus:ring-white/40"
              >
                <option value="all">All</option>
                {languages.map(lang => (
                  <option key={lang} value={lang}>
                    {lang}
                  </option>
                ))}
              </select>
            </div>
            {/* All repos link */}
            <a
              href={`${GITEA_URL}/${GITEA_USERNAME}`}
              target="_blank"
              rel="noopener noreferrer"
              className="hidden sm:inline-flex items-center gap-1.5 text-xs text-white/30 hover:text-white/60 transition-colors"
            >
              All repos
              <svg
                width="12"
                height="12"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                strokeWidth="2"
                aria-hidden="true"
              >
                <path d="M7 17L17 7M7 7h10v10" />
              </svg>
            </a>
          </div>
        </div>

        {/* Loading */}
        {!filteredRepos && !error && (
          <div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-4">
            {Array.from({ length: 6 }).map((_, i) => (
              <div key={i} className="glass rounded-2xl p-5 flex flex-col gap-3">
                <div className="skel h-4 w-1/2" />
                <div className="skel h-3 w-5/6" />
                <div className="skel h-3 w-3/4" />
                <div className="skel h-3 w-1/3 mt-auto" />
              </div>
            ))}
          </div>
        )}

        {/* Error */}
        {error && (
          <div className="glass rounded-2xl p-10 text-center">
            <p className="text-white/30 text-sm mb-1">
              Could not load repositories
            </p>
            <p className="text-white/20 text-xs">{error}</p>
          </div>
        )}

        {/* Repos list */}
        {filteredRepos && (
          <div
            className="grid sm:grid-cols-2 lg:grid-cols-3 gap-4"
            aria-live="polite"
          >
            {filteredRepos.map(repo => {
              const updated = repo.updated || (repo as any).updated_at;

              return (
                <button
                  key={repo.id}
                  type="button"
                  onClick={() => setActiveRepo(repo)}
                  className="glass rounded-2xl p-5 flex flex-col gap-4 group transition-all duration-200 text-left
                    hover:border-white/[0.14] hover:shadow-[0_0_0_1px_rgba(0,0,0,0.6),0_16px_48px_rgba(0,0,0,0.6)]
                    hover:-translate-y-[2px] cursor-pointer"
                  aria-label={`${repo.name}: ${repo.description || 'No description'}`}
                >
                  <div className="flex items-start justify-between gap-2">
                    <div
                      className="p-1.5 rounded-md bg-white/[0.04] border border-white/[0.07]"
                      aria-hidden="true"
                    >
                      <svg
                        width="14"
                        height="14"
                        viewBox="0 0 24 24"
                        fill="none"
                        stroke="rgba(255,255,255,0.4)"
                        strokeWidth="1.8"
                      >
                        <path d="M15 22v-4a4.8 4.8 0 0 0-1-3.2c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4" />
                        <path d="M9 18c-4.51 2-5-2-7-2" />
                      </svg>
                    </div>
                    <svg
                      className="text-white/20 group-hover:text-white/40 transition-colors"
                      width="12"
                      height="12"
                      viewBox="0 0 24 24"
                      fill="none"
                      stroke="currentColor"
                      strokeWidth="2"
                      aria-hidden="true"
                    >
                      <path d="M7 17L17 7M7 7h10v10" />
                    </svg>
                  </div>

                  <div>
                    <p className="text-sm font-semibold text-white mb-1 truncate">
                      {repo.name}
                    </p>
                    <p className="text-xs text-white/35 leading-relaxed line-clamp-2">
                      {repo.description ? (
                        repo.description
                      ) : (
                        <span className="italic text-white/20">
                          No description
                        </span>
                      )}
                    </p>
                  </div>

                  <div className="flex items-center gap-4 mt-auto">
                    {repo.language && (
                      <span className="flex items-center gap-1.5 text-xs text-white/30">
                        <span
                          className="w-2 h-2 rounded-full flex-shrink-0"
                          style={{ background: langColor(repo.language) }}
                          aria-hidden="true"
                        />
                        {repo.language}
                      </span>
                    )}
                    <span
                      className="flex items-center gap-1 text-xs text-white/25"
                      aria-label={`${repo.stars_count} stars`}
                    >
                      <svg
                        width="10"
                        height="10"
                        viewBox="0 0 24 24"
                        fill="currentColor"
                        aria-hidden="true"
                      >
                        <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" />
                      </svg>
                      {repo.stars_count}
                    </span>
                    <span className="text-xs text-white/20 ml-auto tabular-nums">
                      {timeAgo(updated)}
                    </span>
                  </div>
                </button>
              );
            })}
          </div>
        )}

        {/* Popout with README + Live + Wiki (unchanged) */}
        {activeRepo && (
          <div
            className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 px-4"
            role="dialog"
            aria-modal="true"
            aria-label={`${activeRepo.name} details`}
          >
            <div className="glass max-w-2xl w-full rounded-2xl p-5 sm:p-6 relative max-h-[80vh] overflow-hidden flex flex-col">
              <button
                type="button"
                onClick={() => {
                  setActiveRepo(null);
                  setReadmeHtml(null);
                  setReadmeError(null);
                }}
                className="absolute top-3 right-3 text-white/40 hover:text-white/80"
                aria-label="Close"
              >
                <svg
                  width="16"
                  height="16"
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="2"
                >
                  <path d="M6 6l12 12M6 18L18 6" />
                </svg>
              </button>

              <header className="mb-3 pr-8">
                <h3 className="text-sm font-semibold text-white mb-1">
                  {activeRepo.name}
                </h3>
                <p className="text-xs text-white/40">
                  {activeRepo.description ||
                    'This project does not have a description yet.'}
                </p>
              </header>

              <div className="flex items-center gap-2 mb-4 text-xs">
                <a
                  href={activeRepo.html_url}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="inline-flex items-center gap-1 px-3 py-1 rounded-full bg-white/5 border border-white/15 text-white/80 hover:bg-white/8"
                >
                  View code
                </a>
                {activeRepo.website &&
                  activeRepo.website.trim().length > 0 && (
                    <a
                      href={activeRepo.website}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="inline-flex items-center gap-1 px-3 py-1 rounded-full bg-white/5 border border-white/15 text-white/80 hover:bg-white/8"
                    >
                      View live
                    </a>
                  )}
                <a
                  href={`https://git.williammarch.xyz/${GITEA_USERNAME}/${activeRepo.name}/wiki`}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="inline-flex items-center gap-1 px-3 py-1 rounded-full bg-white/5 border border-white/15 text-white/80 hover:bg-white/8"
                >
                  Wiki
                </a>
              </div>

              <div className="flex-1 overflow-y-auto pr-1 text-xs leading-relaxed text-white/70">
                {readmeLoading && (
                  <p className="text-white/40">Loading README…</p>
                )}
                {readmeError && (
                  <p className="text-white/40">
                    Could not load README: {readmeError}
                  </p>
                )}
                {readmeHtml && (
                  <div
                    className="prose prose-invert prose-sm max-w-none"
                    dangerouslySetInnerHTML={{ __html: readmeHtml }}
                  />
                )}
                {!readmeLoading && !readmeError && !readmeHtml && (
                  <p className="text-white/40">
                    No README content available for this repository.
                  </p>
                )}
              </div>
            </div>
          </div>
        )}
      </div>
    </section>
  );
}
