// Package webui provides the web interface for the sketch loop.
// It bundles typescript files into JavaScript using esbuild.
package webui

import (
	"archive/zip"
	"bytes"
	"compress/gzip"
	"crypto/sha256"
	"embed"
	"encoding/hex"
	"fmt"
	"io"
	"io/fs"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	esbuildcli "github.com/evanw/esbuild/pkg/cli"
)

//go:embed package.json package-lock.json src tsconfig.json
var embedded embed.FS

//go:generate go run ../cmd/go2ts -o src/types.ts

func embeddedHash() (string, error) {
	h := sha256.New()
	err := fs.WalkDir(embedded, ".", func(path string, d fs.DirEntry, err error) error {
		if d.IsDir() {
			return nil
		}
		f, err := embedded.Open(path)
		if err != nil {
			return err
		}
		defer f.Close()
		if _, err := io.Copy(h, f); err != nil {
			return fmt.Errorf("%s: %w", path, err)
		}
		return nil
	})
	if err != nil {
		return "", fmt.Errorf("embedded hash: %w", err)
	}
	return hex.EncodeToString(h.Sum(nil))[:32], nil
}

// ensureNodeModules runs npm ci only if package-lock.json has changed or node_modules doesn't exist.
// This optimization saves ~2.4 seconds when only TypeScript or other source files change,
// since npm ci is only run when dependencies actually change.
func ensureNodeModules(buildDir string) error {
	packageLockPath := filepath.Join(buildDir, "package-lock.json")
	nodeModulesPath := filepath.Join(buildDir, "node_modules")
	packageLockBackupPath := filepath.Join(buildDir, ".package-lock-installed")

	// Check if node_modules exists
	if _, err := os.Stat(nodeModulesPath); os.IsNotExist(err) {
		fmt.Printf("[BUILD] node_modules doesn't exist, running npm ci...\n")
		return runNpmCI(buildDir, packageLockPath, packageLockBackupPath)
	}

	// Read current package-lock.json
	packageLockData, err := os.ReadFile(packageLockPath)
	if err != nil {
		return fmt.Errorf("read package-lock.json: %w", err)
	}

	// Check if package-lock.json has changed by comparing with stored version
	if storedPackageLockData, err := os.ReadFile(packageLockBackupPath); err == nil {
		if bytes.Equal(packageLockData, storedPackageLockData) {
			fmt.Printf("[BUILD] package-lock.json unchanged, skipping npm ci\n")
			return nil
		}
	}

	fmt.Printf("[BUILD] package-lock.json changed, running npm ci...\n")
	return runNpmCI(buildDir, packageLockPath, packageLockBackupPath)
}

// runNpmCI executes npm ci and stores the package-lock.json content
func runNpmCI(buildDir, packageLockPath, packageLockBackupPath string) error {
	start := time.Now()
	cmd := exec.Command("npm", "ci", "--omit", "dev")
	cmd.Dir = buildDir
	if out, err := cmd.CombinedOutput(); err != nil {
		return fmt.Errorf("npm ci: %s: %v", out, err)
	}
	fmt.Printf("[BUILD] npm ci completed in %v\n", time.Since(start))

	// Store a copy of package-lock.json for future comparisons
	packageLockData, err := os.ReadFile(packageLockPath)
	if err != nil {
		return fmt.Errorf("read package-lock.json after npm ci: %w", err)
	}

	if err := os.WriteFile(packageLockBackupPath, packageLockData, 0o666); err != nil {
		return fmt.Errorf("write package-lock backup: %w", err)
	}

	return nil
}

func cleanBuildDir(buildDir string) error {
	err := fs.WalkDir(os.DirFS(buildDir), ".", func(path string, d fs.DirEntry, err error) error {
		if d.Name() == "." {
			return nil
		}
		if d.Name() == "node_modules" {
			return fs.SkipDir
		}
		if d.Name() == ".package-lock-installed" {
			return nil // Skip file, but don't skip directory
		}
		osPath := filepath.Join(buildDir, path)
		os.RemoveAll(osPath)
		if d.IsDir() {
			return fs.SkipDir
		}
		return nil
	})
	if err != nil {
		return fmt.Errorf("clean build dir: %w", err)
	}
	return nil
}

func unpackFS(out string, srcFS fs.FS) error {
	err := fs.WalkDir(srcFS, ".", func(path string, d fs.DirEntry, err error) error {
		if d.Name() == "." {
			return nil
		}
		if d.IsDir() {
			if err := os.Mkdir(filepath.Join(out, path), 0o777); err != nil {
				return err
			}
			return nil
		}
		f, err := srcFS.Open(path)
		if err != nil {
			return err
		}
		defer f.Close()
		dst, err := os.Create(filepath.Join(out, path))
		if err != nil {
			return err
		}
		defer dst.Close()
		if _, err := io.Copy(dst, f); err != nil {
			return err
		}
		if err := dst.Close(); err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		return fmt.Errorf("unpack fs into out dir %s: %w", out, err)
	}
	return nil
}

// TODO: This path being /root/.cache/sketch/webui/skui-....zip means that the Dockerfile
// in createdockerfile.go needs to create the parent directory. Ideally we bundle the built webui
// into the binary and avoid this altogether.
func zipPath() (cacheDir, hashZip string, err error) {
	homeDir, err := os.UserHomeDir()
	if err != nil {
		return "", "", err
	}
	hash, err := embeddedHash()
	if err != nil {
		return "", "", err
	}
	cacheDir = filepath.Join(homeDir, ".cache", "sketch", "webui")
	return cacheDir, filepath.Join(cacheDir, "skui-"+hash+".zip"), nil
}

// generateTailwindCSS generates tailwind.css from global.css and outputs it to the specified directory
func generateTailwindCSS(buildDir, outDir string) error {
	// Run tailwindcss CLI to generate the CSS
	cmd := exec.Command("npx", "tailwindcss", "-i", "./src/global.css", "-o", filepath.Join(outDir, "tailwind.css"))
	cmd.Dir = buildDir
	if out, err := cmd.CombinedOutput(); err != nil {
		return fmt.Errorf("tailwindcss generation failed: %s: %v", out, err)
	}
	return nil
}

// copyMonacoAssets copies Monaco editor assets to the output directory
func copyMonacoAssets(buildDir, outDir string) error {
	// Create Monaco directories
	monacoEditorDir := filepath.Join(outDir, "monaco", "min", "vs", "editor")
	codiconDir := filepath.Join(outDir, "monaco", "min", "vs", "base", "browser", "ui", "codicons", "codicon")

	if err := os.MkdirAll(monacoEditorDir, 0o777); err != nil {
		return fmt.Errorf("failed to create monaco editor directory: %w", err)
	}

	if err := os.MkdirAll(codiconDir, 0o777); err != nil {
		return fmt.Errorf("failed to create codicon directory: %w", err)
	}

	// Copy Monaco editor CSS
	editorCssPath := "node_modules/monaco-editor/min/vs/editor/editor.main.css"
	editorCss, err := os.ReadFile(filepath.Join(buildDir, editorCssPath))
	if err != nil {
		return fmt.Errorf("failed to read monaco editor CSS: %w", err)
	}

	if err := os.WriteFile(filepath.Join(monacoEditorDir, "editor.main.css"), editorCss, 0o666); err != nil {
		return fmt.Errorf("failed to write monaco editor CSS: %w", err)
	}

	// Copy Codicon font
	codiconFontPath := "node_modules/monaco-editor/min/vs/base/browser/ui/codicons/codicon/codicon.ttf"
	codiconFont, err := os.ReadFile(filepath.Join(buildDir, codiconFontPath))
	if err != nil {
		return fmt.Errorf("failed to read codicon font: %w", err)
	}

	if err := os.WriteFile(filepath.Join(codiconDir, "codicon.ttf"), codiconFont, 0o666); err != nil {
		return fmt.Errorf("failed to write codicon font: %w", err)
	}

	return nil
}

// Build unpacks and esbuild's all bundleTs typescript files
func Build() (fs.FS, error) {
	cacheDir, hashZip, err := zipPath()
	if err != nil {
		return nil, err
	}
	buildDir := filepath.Join(cacheDir, "build")
	if err := os.MkdirAll(buildDir, 0o777); err != nil { // make sure .cache/sketch/build exists
		return nil, err
	}
	if b, err := os.ReadFile(hashZip); err == nil {
		// Build already done, serve it out.
		return zip.NewReader(bytes.NewReader(b), int64(len(b)))
	}

	// TODO: try downloading "https://sketch.dev/webui/"+filepath.Base(hashZip)

	// We need to do a build.
	fmt.Printf("[BUILD] Starting webui build process...\n")
	buildStart := time.Now()

	// Clear everything out of the build directory except node_modules.
	fmt.Printf("[BUILD] Cleaning build directory...\n")
	if err := cleanBuildDir(buildDir); err != nil {
		return nil, err
	}
	tmpHashDir := filepath.Join(buildDir, "out")
	if err := os.MkdirAll(tmpHashDir, 0o777); err != nil {
		return nil, err
	}

	// Unpack everything from embedded into build dir.
	fmt.Printf("[BUILD] Unpacking embedded files...\n")
	if err := unpackFS(buildDir, embedded); err != nil {
		return nil, err
	}

	// Do the build. Don't install dev dependencies, because they can be large
	// and slow enough to install that the /init requests from the host process
	// will run out of retries and the whole thing exits. We do need better health
	// checking in general, but that's a separate issue. Don't do slow stuff here:
	if err := ensureNodeModules(buildDir); err != nil {
		return nil, fmt.Errorf("ensure node modules: %w", err)
	}

	// Generate Tailwind CSS
	if err := generateTailwindCSS(buildDir, tmpHashDir); err != nil {
		return nil, fmt.Errorf("generate tailwind css: %w", err)
	}
	// Create all bundles
	bundleTs := []string{
		"src/web-components/sketch-app-shell.ts",
		"src/web-components/mobile-app-shell.ts",
		"src/web-components/sketch-monaco-view.ts",
		"src/messages-viewer.ts",
		"node_modules/monaco-editor/esm/vs/editor/editor.worker.js",
		"node_modules/monaco-editor/esm/vs/language/typescript/ts.worker.js",
		"node_modules/monaco-editor/esm/vs/language/html/html.worker.js",
		"node_modules/monaco-editor/esm/vs/language/css/css.worker.js",
		"node_modules/monaco-editor/esm/vs/language/json/json.worker.js",
	}

	// Additionally create standalone bundles for caching
	monacoHash, err := createStandaloneMonacoBundle(tmpHashDir, buildDir)
	if err != nil {
		return nil, fmt.Errorf("create monaco bundle: %w", err)
	}

	mermaidHash, err := createStandaloneMermaidBundle(tmpHashDir, buildDir)
	if err != nil {
		return nil, fmt.Errorf("create mermaid bundle: %w", err)
	}

	// Bundle all files with Monaco and Mermaid as external (since they may transitively import them)
	for _, tsName := range bundleTs {
		// Use external Monaco and Mermaid for all TypeScript files to ensure consistency
		if strings.HasSuffix(tsName, ".ts") {
			if err := esbuildBundleWithExternals(tmpHashDir, filepath.Join(buildDir, tsName), monacoHash, mermaidHash); err != nil {
				return nil, fmt.Errorf("esbuild: %s: %w", tsName, err)
			}
		} else {
			// Bundle worker files normally (they don't use Monaco or Mermaid)
			if err := esbuildBundle(tmpHashDir, filepath.Join(buildDir, tsName), ""); err != nil {
				return nil, fmt.Errorf("esbuild: %s: %w", tsName, err)
			}
		}
	}

	// Copy Monaco editor assets
	if err := copyMonacoAssets(buildDir, tmpHashDir); err != nil {
		return nil, fmt.Errorf("failed to copy Monaco assets: %w", err)
	}

	// Copy src files used directly into the new hash output dir.
	err = fs.WalkDir(embedded, "src", func(path string, d fs.DirEntry, err error) error {
		if d.IsDir() {
			if path == "src/web-components/demo" {
				return fs.SkipDir
			}
			return nil
		}
		if strings.HasSuffix(path, "mockServiceWorker.js") {
			return nil
		}
		// Skip src/tailwind.css as it will be generated
		if path == "src/tailwind.css" {
			return nil
		}
		if strings.HasSuffix(path, ".html") || strings.HasSuffix(path, ".css") || strings.HasSuffix(path, ".js") {
			b, err := embedded.ReadFile(path)
			if err != nil {
				return err
			}
			dstPath := filepath.Join(tmpHashDir, strings.TrimPrefix(path, "src/"))
			if err := os.WriteFile(dstPath, b, 0o777); err != nil {
				return err
			}
			return nil
		}
		return nil
	})
	if err != nil {
		return nil, err
	}

	// Copy xterm.css from node_modules
	const xtermCssPath = "node_modules/@xterm/xterm/css/xterm.css"
	xtermCss, err := os.ReadFile(filepath.Join(buildDir, xtermCssPath))
	if err != nil {
		return nil, fmt.Errorf("failed to read xterm.css: %w", err)
	}
	if err := os.WriteFile(filepath.Join(tmpHashDir, "xterm.css"), xtermCss, 0o666); err != nil {
		return nil, fmt.Errorf("failed to write xterm.css: %w", err)
	}

	// Compress all .js, .js.map, and .css files with gzip, leaving the originals in place
	err = filepath.Walk(tmpHashDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			return nil
		}
		// Check if file is a .js or .js.map file
		if !strings.HasSuffix(path, ".js") && !strings.HasSuffix(path, ".js.map") && !strings.HasSuffix(path, ".css") {
			return nil
		}

		// Read the original file
		origData, err := os.ReadFile(path)
		if err != nil {
			return fmt.Errorf("failed to read file %s: %w", path, err)
		}

		// Create a gzipped file
		gzipPath := path + ".gz"
		gzipFile, err := os.Create(gzipPath)
		if err != nil {
			return fmt.Errorf("failed to create gzip file %s: %w", gzipPath, err)
		}
		defer gzipFile.Close()

		// Create a gzip writer
		gzWriter := gzip.NewWriter(gzipFile)
		defer gzWriter.Close()

		// Write the original file content to the gzip writer
		_, err = gzWriter.Write(origData)
		if err != nil {
			return fmt.Errorf("failed to write to gzip file %s: %w", gzipPath, err)
		}

		// Ensure we flush and close properly
		if err := gzWriter.Close(); err != nil {
			return fmt.Errorf("failed to close gzip writer for %s: %w", gzipPath, err)
		}
		if err := gzipFile.Close(); err != nil {
			return fmt.Errorf("failed to close gzip file %s: %w", gzipPath, err)
		}

		// The gzip handler will decompress on-the-fly for browsers that don't support gzip.
		if err := os.Remove(path); err != nil {
			return fmt.Errorf("failed to remove uncompressed file %s: %w", path, err)
		}

		return nil
	})
	if err != nil {
		return nil, fmt.Errorf("failed to compress .js/.js.map/.css files: %w", err)
	}

	fmt.Printf("[BUILD] Build completed in %v\n", time.Since(buildStart))
	return os.DirFS(tmpHashDir), nil
}

func esbuildBundle(outDir, src, metafilePath string) error {
	args := []string{
		src,
		"--bundle",
		"--sourcemap",
		"--log-level=error",
		"--minify",
		"--outdir=" + outDir,
		"--loader:.ttf=file",
		"--loader:.eot=file",
		"--loader:.woff=file",
		"--loader:.woff2=file",
		// This changes where the sourcemap points to; we need relative dirs if we're proxied into a subdirectory.
		"--public-path=.",
	}

	// Add metafile option if path is provided
	if metafilePath != "" {
		args = append(args, "--metafile="+metafilePath)
	}

	ret := esbuildcli.Run(args)
	if ret != 0 {
		return fmt.Errorf("esbuild %s failed: %d", filepath.Base(src), ret)
	}
	return nil
}

// unpackTS unpacks all the typescript-relevant files from the embedded filesystem into tmpDir.
func unpackTS(outDir string, embedded fs.FS) error {
	return fs.WalkDir(embedded, ".", func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}
		tgt := filepath.Join(outDir, path)
		if d.IsDir() {
			if err := os.MkdirAll(tgt, 0o777); err != nil {
				return err
			}
			return nil
		}
		if strings.HasSuffix(path, ".html") || strings.HasSuffix(path, ".md") || strings.HasSuffix(path, ".css") {
			return nil
		}
		data, err := fs.ReadFile(embedded, path)
		if err != nil {
			return err
		}
		if err := os.WriteFile(tgt, data, 0o666); err != nil {
			return err
		}
		return nil
	})
}

// GenerateBundleMetafile creates metafiles for bundle analysis with esbuild.
//
// The metafiles contain information about bundle size and dependencies
// that can be visualized at https://esbuild.github.io/analyze/
//
// It takes the output directory where the metafiles will be written.
// Returns the file path of the generated metafiles.
func GenerateBundleMetafile(outputDir string) (string, error) {
	tmpDir, err := os.MkdirTemp("", "bundle-analysis-")
	if err != nil {
		return "", err
	}
	defer os.RemoveAll(tmpDir)

	// Create output directory if it doesn't exist
	if err := os.MkdirAll(outputDir, 0o755); err != nil {
		return "", err
	}

	cacheDir, _, err := zipPath()
	if err != nil {
		return "", err
	}
	buildDir := filepath.Join(cacheDir, "build")
	if err := os.MkdirAll(buildDir, 0o777); err != nil { // make sure .cache/sketch/build exists
		return "", err
	}

	// Ensure we have a source to bundle
	if err := unpackTS(tmpDir, embedded); err != nil {
		return "", err
	}

	// All bundles to analyze
	bundleTs := []string{
		"src/web-components/sketch-app-shell.ts",
		"src/web-components/mobile-app-shell.ts",
		"src/web-components/sketch-monaco-view.ts",
		"src/messages-viewer.ts",
	}
	metafiles := make([]string, len(bundleTs))

	for i, tsName := range bundleTs {
		// Create a metafile path for this bundle
		baseFileName := filepath.Base(tsName)
		metaFileName := strings.TrimSuffix(baseFileName, ".ts") + ".meta.json"
		metafilePath := filepath.Join(outputDir, metaFileName)
		metafiles[i] = metafilePath

		// Bundle with metafile generation
		outTmpDir, err := os.MkdirTemp("", "metafile-bundle-")
		if err != nil {
			return "", err
		}
		defer os.RemoveAll(outTmpDir)

		if err := esbuildBundle(outTmpDir, filepath.Join(buildDir, tsName), metafilePath); err != nil {
			return "", fmt.Errorf("failed to generate metafile for %s: %w", tsName, err)
		}
	}

	return outputDir, nil
}

// createStandaloneMonacoBundle creates a separate Monaco editor bundle with content-based hash
// This is useful for caching Monaco separately from the main application bundles
func createStandaloneMonacoBundle(outDir, buildDir string) (string, error) {
	// Create a temporary entry file that imports Monaco and exposes it globally
	monacoEntryContent := `import * as monaco from 'monaco-editor';
window.monaco = monaco;
export default monaco;
`
	monacoEntryPath := filepath.Join(buildDir, "monaco-standalone-entry.js")
	if err := os.WriteFile(monacoEntryPath, []byte(monacoEntryContent), 0o666); err != nil {
		return "", fmt.Errorf("write monaco entry: %w", err)
	}

	// Calculate hash of monaco-editor package for content-based naming
	monacoPackageJson := filepath.Join(buildDir, "node_modules", "monaco-editor", "package.json")
	monacoContent, err := os.ReadFile(monacoPackageJson)
	if err != nil {
		return "", fmt.Errorf("read monaco package.json: %w", err)
	}

	h := sha256.New()
	h.Write(monacoContent)
	monacoHash := hex.EncodeToString(h.Sum(nil))[:16]

	// Bundle Monaco with content-based filename
	monacoOutputName := fmt.Sprintf("monaco-standalone-%s.js", monacoHash)
	monacoOutputPath := filepath.Join(outDir, monacoOutputName)

	args := []string{
		monacoEntryPath,
		"--bundle",
		"--sourcemap",
		"--minify",
		"--log-level=error",
		"--outfile=" + monacoOutputPath,
		"--format=iife",
		"--global-name=__MonacoLoader__",
		"--loader:.ttf=file",
		"--loader:.eot=file",
		"--loader:.woff=file",
		"--loader:.woff2=file",
		"--public-path=.",
	}

	ret := esbuildcli.Run(args)
	if ret != 0 {
		return "", fmt.Errorf("esbuild monaco bundle failed: %d", ret)
	}

	return monacoHash, nil
}

// createStandaloneMermaidBundle creates a separate Mermaid bundle with content-based hash
// This is useful for caching Mermaid separately from the main application bundles
func createStandaloneMermaidBundle(outDir, buildDir string) (string, error) {
	// Create a temporary entry file that imports Mermaid and exposes it globally
	mermaidEntryContent := `import mermaid from 'mermaid';
window.mermaid = mermaid;
export default mermaid;
`
	mermaidEntryPath := filepath.Join(buildDir, "mermaid-standalone-entry.js")
	if err := os.WriteFile(mermaidEntryPath, []byte(mermaidEntryContent), 0o666); err != nil {
		return "", fmt.Errorf("write mermaid entry: %w", err)
	}

	// Calculate hash of mermaid package for content-based naming
	mermaidPackageJson := filepath.Join(buildDir, "node_modules", "mermaid", "package.json")
	mermaidContent, err := os.ReadFile(mermaidPackageJson)
	if err != nil {
		return "", fmt.Errorf("read mermaid package.json: %w", err)
	}

	h := sha256.New()
	h.Write(mermaidContent)
	mermaidHash := hex.EncodeToString(h.Sum(nil))[:16]

	// Bundle Mermaid with content-based filename
	mermaidOutputName := fmt.Sprintf("mermaid-standalone-%s.js", mermaidHash)
	mermaidOutputPath := filepath.Join(outDir, mermaidOutputName)

	args := []string{
		mermaidEntryPath,
		"--bundle",
		"--sourcemap",
		"--minify",
		"--log-level=error",
		"--outfile=" + mermaidOutputPath,
		"--format=iife",
		"--global-name=__MermaidLoader__",
		"--loader:.ttf=file",
		"--loader:.eot=file",
		"--loader:.woff=file",
		"--loader:.woff2=file",
		"--public-path=.",
	}

	ret := esbuildcli.Run(args)
	if ret != 0 {
		return "", fmt.Errorf("esbuild mermaid bundle failed: %d", ret)
	}

	return mermaidHash, nil
}

// esbuildBundleWithExternals bundles a file with Monaco and Mermaid as external dependencies
func esbuildBundleWithExternals(outDir, src, monacoHash, mermaidHash string) error {
	args := []string{
		src,
		"--bundle",
		"--sourcemap",
		"--minify",
		"--log-level=error",
		"--outdir=" + outDir,
		"--external:monaco-editor",
		"--external:mermaid",
		"--loader:.ttf=file",
		"--loader:.eot=file",
		"--loader:.woff=file",
		"--loader:.woff2=file",
		"--public-path=.",
		"--define:__MONACO_HASH__=\"" + monacoHash + "\"",
		"--define:__MERMAID_HASH__=\"" + mermaidHash + "\"",
	}

	ret := esbuildcli.Run(args)
	if ret != 0 {
		return fmt.Errorf("esbuild %s failed: %d", filepath.Base(src), ret)
	}
	return nil
}
