"use client";

import { useEffect, useRef, useCallback } from "react";
import hljs from "highlight.js/lib/core";
import nix from "highlight.js/lib/languages/nix";
import "highlight.js/styles/github-dark.css";

hljs.registerLanguage("nix", nix);

declare global {
    interface Window {
        showSaveFilePicker?: (options?: {
            suggestedName?: string;
            types?: Array<{
                description?: string;
                accept: Record<string, string[]>;
            }>;
        }) => Promise<FileSystemFileHandle>;
    }
}

const code = `{
    description = "My personal website";
    
    inputs = {
        nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    }

    outputs = { self, nixpkgs }: {
        let
            system = "x86_64-linux";
            pkgs = import nixpkgs { inherit system; };
        in {
            // install pakages
            nix.settings = {
                sandbox = false;
                experimental-features = [ "flakes" ];
            };
            time.timeZone = "Asia/Seoul";
        }
}`;

const customTheme = `
.hljs {
  background: #191017 !important;
  color: #fcf8f9 !important;
}
.hljs-attr { color: #f38ba8; }
.hljs-string { color: #a6e3a1; }
.hljs-number { color: #f9e2af; }
.hljs-literal { color: #89b4fa; }
.hljs-type { color: #f5c2e7; }
.hljs-title { color: #94e2d5; }
`;

export default function FlakeNix() {
    const codeRef = useRef<HTMLElement>(null);

    const downloadFile = useCallback(async () => {
        if (window.showSaveFilePicker) {
            try {
                const handle = await window.showSaveFilePicker({
                    suggestedName: "flake.nix",
                    types: [
                        {
                            description: "Nix Files",
                            accept: { "text/plain": [".nix"] },
                        },
                    ],
                });
                const writable = await handle.createWritable();
                await writable.write(code);
                await writable.close();
            } catch (e) {
                // 사용자가 취소한 경우
                if ((e as Error).name !== "AbortError") {
                    console.error(e);
                }
            }
        } else {
            // fallback: showSaveFilePicker를 지원하지 않는 브라우저
            const blob = new Blob([code], { type: "text/plain" });
            const url = URL.createObjectURL(blob);
            const a = document.createElement("a");
            a.href = url;
            a.download = "flake.nix";
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        }
    }, []);

    useEffect(() => {
        const style = document.createElement("style");
        style.textContent = customTheme;
        document.head.appendChild(style);

        if (codeRef.current) {
            hljs.highlightElement(codeRef.current);
        }

        const handleKeyDown = (e: KeyboardEvent) => {
            if ((e.ctrlKey || e.metaKey) && e.key === "s") {
                e.preventDefault();
                downloadFile();
            }
        };

        window.addEventListener("keydown", handleKeyDown);

        return () => {
            window.removeEventListener("keydown", handleKeyDown);
        };
    }, [downloadFile]);

    return (
        <main className="flex h-screen items-center justify-center">
            <div className="max-w-3xl w-full mx-auto px-6 rounded-2xl overflow-auto">
                <pre>
                    <code ref={codeRef} className="language-nix">
                        {code}
                    </code>
                </pre>
            </div>
        </main>
    );
}