"use client"

import { useCallback, useEffect, useRef, useState } from "react"
import { emit } from "@tauri-apps/api/event"
import { Check, FileWarning, Loader2, X, CheckCheck } from "lucide-react"
import { useTranslations } from "next-intl"
import { toast } from "sonner"
import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Button } from "@/components/ui/button"
import {
  gitListConflicts,
  gitConflictFileVersions,
  gitResolveConflict,
  gitAbortOperation,
  gitContinueOperation,
  gitStartPullMerge,
} from "@/lib/tauri"
import { languageFromPath } from "@/lib/language-detect"
import { toErrorMessage } from "@/lib/app-error"
import type { GitConflictFileVersions } from "@/lib/types"
import { ThreePaneMergeEditor } from "./three-pane-merge-editor"

interface MergeWorkspaceProps {
  folderId: number
  folderPath: string
  operation: string
  upstreamCommit?: string
  onCompleted: () => void
  onAborted: () => void
}

export function MergeWorkspace({
  folderId,
  folderPath,
  operation,
  upstreamCommit,
  onCompleted,
  onAborted,
}: MergeWorkspaceProps) {
  const t = useTranslations("MergePage")
  const [files, setFiles] = useState<string[]>([])
  const [resolvedFiles, setResolvedFiles] = useState<Set<string>>(new Set())
  const [selectedFile, setSelectedFile] = useState<string | null>(null)
  const [versions, setVersions] = useState<GitConflictFileVersions | null>(null)
  const [loadingVersions, setLoadingVersions] = useState(false)
  const [resolving, setResolving] = useState(false)
  const [aborting, setAborting] = useState(false)
  const [completing, setCompleting] = useState(false)
  const currentContentRef = useRef<string>("")
  const [hasUnresolvedConflicts, setHasUnresolvedConflicts] = useState(true)
  const [preparing, setPreparing] = useState(false)

  // Load conflict files on mount
  useEffect(() => {
    loadConflicts()
  }, [folderPath]) // eslint-disable-line react-hooks/exhaustive-deps

  async function loadConflicts() {
    try {
      // For pull operations, the merge was aborted during detection to keep
      // working tree clean. Re-start the merge to create conflict state.
      if (operation === "pull") {
        setPreparing(true)
        try {
          await gitStartPullMerge(folderPath, upstreamCommit)
        } finally {
          setPreparing(false)
        }
      }
      const conflictFiles = await gitListConflicts(folderPath)
      setFiles(conflictFiles)
      if (conflictFiles.length > 0 && !selectedFile) {
        selectFile(conflictFiles[0])
      }
    } catch (err) {
      toast.error(toErrorMessage(err))
    }
  }

  async function selectFile(file: string) {
    setSelectedFile(file)
    setLoadingVersions(true)
    try {
      const v = await gitConflictFileVersions(folderPath, file)
      setVersions(v)
      currentContentRef.current = v.base
      setHasUnresolvedConflicts(true)
    } catch (err) {
      toast.error(toErrorMessage(err))
      setVersions(null)
    } finally {
      setLoadingVersions(false)
    }
  }

  const handleContentChange = useCallback((content: string) => {
    currentContentRef.current = content
  }, [])

  const handleConflictStatusChange = useCallback((hasUnresolved: boolean) => {
    setHasUnresolvedConflicts(hasUnresolved)
  }, [])

  async function handleResolve() {
    if (!selectedFile) return

    const content = currentContentRef.current
    if (hasUnresolvedConflicts) {
      toast.warning(t("unresolvedConflicts"))
      return
    }

    setResolving(true)
    try {
      await gitResolveConflict(folderPath, selectedFile, content)
      setResolvedFiles((prev) => new Set([...prev, selectedFile]))

      // Notify parent window
      await emit("folder://merge-conflict-resolved", {
        folder_id: folderId,
        file: selectedFile,
      })

      // Auto-select next unresolved file
      const nextUnresolved = files.find(
        (f) => f !== selectedFile && !resolvedFiles.has(f)
      )
      if (nextUnresolved) {
        selectFile(nextUnresolved)
      }
    } catch (err) {
      toast.error(toErrorMessage(err))
    } finally {
      setResolving(false)
    }
  }

  async function handleAbort() {
    setAborting(true)
    try {
      await gitAbortOperation(folderPath, operation)
      toast.success(t("abortSuccess"))
      await emit("folder://merge-aborted", { folder_id: folderId })
      onAborted()
    } catch (err) {
      toast.error(toErrorMessage(err))
    } finally {
      setAborting(false)
    }
  }

  async function handleComplete() {
    setCompleting(true)
    try {
      await gitContinueOperation(folderPath, operation)
      toast.success(t("allResolved"))
      await emit("folder://merge-completed", { folder_id: folderId })
      onCompleted()
    } catch (err) {
      toast.error(toErrorMessage(err))
    } finally {
      setCompleting(false)
    }
  }

  const allResolved =
    files.length > 0 && files.every((f) => resolvedFiles.has(f))

  const language = selectedFile ? languageFromPath(selectedFile) : "plaintext"

  return (
    <div className="flex h-full flex-col gap-2">
      <ResizablePanelGroup
        direction="horizontal"
        className="flex-1 min-h-0 rounded-lg border"
      >
        {/* Left sidebar: conflict file list */}
        <ResizablePanel defaultSize={18} minSize={12} maxSize={30}>
          <div className="flex h-full flex-col">
            <div className="border-b px-3 py-2 text-xs font-medium text-muted-foreground">
              {t("conflictFiles")} ({files.length})
            </div>
            <ScrollArea className="flex-1">
              <div className="p-1">
                {files.map((file) => {
                  const isResolved = resolvedFiles.has(file)
                  const isSelected = file === selectedFile
                  return (
                    <button
                      key={file}
                      type="button"
                      className={`flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs transition-colors ${
                        isSelected
                          ? "bg-accent text-accent-foreground"
                          : "hover:bg-accent/50"
                      }`}
                      onClick={() => !isResolved && selectFile(file)}
                      disabled={isResolved}
                    >
                      {isResolved ? (
                        <Check className="h-3 w-3 shrink-0 text-green-500" />
                      ) : (
                        <FileWarning className="h-3 w-3 shrink-0 text-amber-500" />
                      )}
                      <span
                        className={`truncate ${isResolved ? "text-muted-foreground line-through" : ""}`}
                      >
                        {file}
                      </span>
                    </button>
                  )
                })}
                {files.length === 0 && (
                  <div className="px-2 py-4 text-center text-xs text-muted-foreground">
                    {t("noConflicts")}
                  </div>
                )}
              </div>
            </ScrollArea>
          </div>
        </ResizablePanel>

        <ResizableHandle />

        {/* Main area: three-pane merge editor */}
        <ResizablePanel defaultSize={82}>
          {preparing ? (
            <div className="flex h-full items-center justify-center text-sm text-muted-foreground">
              <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              {t("preparingMerge")}
            </div>
          ) : loadingVersions ? (
            <div className="flex h-full items-center justify-center text-sm text-muted-foreground">
              <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              {t("loadingFile")}
            </div>
          ) : versions && selectedFile ? (
            <ThreePaneMergeEditor
              key={selectedFile}
              base={versions.base}
              ours={versions.ours}
              theirs={versions.theirs}
              merged={versions.merged}
              language={language}
              onContentChange={handleContentChange}
              onConflictStatusChange={handleConflictStatusChange}
            />
          ) : (
            <div className="flex h-full items-center justify-center text-sm text-muted-foreground">
              {t("selectFile")}
            </div>
          )}
        </ResizablePanel>
      </ResizablePanelGroup>

      {/* Bottom toolbar */}
      <div className="flex items-center justify-end gap-2">
        <Button
          variant="secondary"
          size="sm"
          onClick={handleAbort}
          disabled={aborting || completing || resolving}
        >
          {aborting && <Loader2 className="mr-1.5 h-3.5 w-3.5 animate-spin" />}
          <X className="mr-1 h-3.5 w-3.5" />
          {t("abortMerge")}
        </Button>
        <Button
          size="sm"
          onClick={handleResolve}
          disabled={
            !selectedFile ||
            resolving ||
            aborting ||
            completing ||
            (selectedFile !== null && resolvedFiles.has(selectedFile))
          }
        >
          {resolving && <Loader2 className="mr-1.5 h-3.5 w-3.5 animate-spin" />}
          <Check className="mr-1 h-3.5 w-3.5" />
          {t("markResolved")}
        </Button>
        {allResolved && (
          <Button
            size="sm"
            onClick={handleComplete}
            disabled={completing || aborting}
          >
            {completing && (
              <Loader2 className="mr-1.5 h-3.5 w-3.5 animate-spin" />
            )}
            <CheckCheck className="mr-1 h-3.5 w-3.5" />
            {t("completeMerge")}
          </Button>
        )}
      </div>
    </div>
  )
}
