'use client'

import type { FolderEntry } from '@/lib/client-types'
import { revokeEntryUrls } from '@/lib/client-object-urls'
import { useSecret } from '@/hooks/useSecret'
import { useFolderEntries } from '@/hooks/useFolderEntries'
import { useUploadOrchestrator } from '@/hooks/useUploadOrchestrator'
import SecretInput from './upload/SecretInput'
import FolderDropzone from './upload/FolderDropzone'
import FolderCard from './upload/FolderCard'
import ActionButtons from './upload/ActionButtons'
import OverwriteConfirmModal from './upload/OverwriteConfirmModal'
import NoChangesModal from './upload/NoChangesModal'
import DriveErrorModal from './upload/DriveErrorModal'
import { WarningIcon } from './ui/icons'

export default function UploadZone() {
  const {
    secret,
    secretError,
    secretVisible,
    isSecretEmpty,
    setSecretError,
    handleSecretChange,
    toggleSecretVisible,
  } = useSecret()

  const {
    entries,
    setEntries,
    updateEntry,
    removeEntry,
    resetEntries,
    allDone,
    hasErrors,
  } = useFolderEntries()

  const {
    isUploading,
    isChecking,
    isResolvingDriveError,
    globalError,
    setGlobalError,
    overwriteConfirm,
    noChangesFolder,
    setNoChangesFolder,
    driveError,
    handleUpload,
    handleOverwriteCancel,
    handleDriveContinue,
    handleDriveCancel,
    handleCancel,
    handleReset,
    proceedUpload,
  } = useUploadOrchestrator({
    secret,
    setSecretError,
    entries,
    updateEntry,
    resetEntries,
  })

  const handleFolderSelected = (entry: FolderEntry) => {
    entries.forEach(revokeEntryUrls)
    setGlobalError(null)
    setEntries([entry])
  }

  const handleToggleViewer = (index: number) => {
    const entry = entries[index]
    if (entry?.modelUrl) {
      updateEntry(index, { viewerOpen: !entry.viewerOpen })
    }
  }

  const hasPendingOrErrors = entries.some((f) => f.status === 'pending' || f.status === 'error')

  return (
    <div className="w-full max-w-3xl space-y-4">
      {entries.length === 0 && (
        <>
          <p className="rounded-2xl border border-white/20 bg-black-800 px-4 py-3 text-xs text-gray-400 leading-relaxed text-center mb-3">
            Deposez un dossier complet contenant votre modele 3D nomme
            {' '}<span className="font-mono text-gray-200">model.gltf</span>
            {' '}ainsi que toutes les textures et fichiers binaires necessaires.
            {' '}Les fichiers associes peuvent etre en
            {' '}<span className="font-mono text-gray-200">.png</span>,
            {' '}<span className="font-mono text-gray-200">.jpg</span>
            {' '}<span className="font-mono text-gray-200">.webp</span>
            {' '}ou <span className="font-mono text-gray-200">.bin</span>.
            {' '}Utilisez un nom simple si la texture s&apos;applique au modele entier, et un nom detaille si elle correspond a une partie precise du modele,
            {' '}par exemple <span className="font-mono text-gray-200">color_porte.jpg</span>,
            {' '}<span className="font-mono text-gray-200">roughness_tuyaux.png</span>,
            {' '}<span className="font-mono text-gray-200">normal_dashboard.webp</span>
            {' '}ou <span className="font-mono text-gray-200">opacity_fenetre.png</span>.
            {' '}Les exports classiques comme <span className="font-mono text-gray-200">porte_baseColor.png</span>
            {' '}ou <span className="font-mono text-gray-200">porte_normal_opengl.png</span> sont normalises automatiquement pour Git.
          </p>
          <div className="mb-3 flex items-start gap-2 rounded-2xl border border-yellow-500/25 bg-yellow-500/10 px-4 py-3 text-xs leading-relaxed text-yellow-200">
            <WarningIcon className="mt-0.5 h-4 w-4 shrink-0 text-yellow-300" />
            <p>
              <span className="font-semibold text-yellow-100">Attention :</span>
              {' '}<span className="font-semibold text-yellow-100">Envoyer</span>
              {' '}genere un GLB quand possible, plus performant pour la deco et les modeles simples.
              {' '}<span className="font-semibold text-yellow-100">Envoyer en GLTF</span>
              {' '}garde des fichiers separes, moins optimises mais plus pratiques pour inspecter et ajuster les noeuds.
              {' '}A privilegier pour les packs de relance, ebikes, pylones et modeles que les devs doivent modifier.
            </p>
          </div>
        </>
      )}

      {entries.length > 0 && (
        <p className="rounded-2xl border border-white/20 bg-black-800 px-4 py-3 text-xs text-gray-400 leading-relaxed text-center mb-3">
          Plus votre dossier est <span className="font-semibold text-gray-200">volumineux</span> et contient de nombreux fichiers,
          {' '}plus l&apos;<span className="font-semibold text-gray-200">upload</span> peut prendre du temps.
          {' '}L&apos;envoi se fait en <span className="font-semibold text-gray-200">3 etapes</span> :
          {' '}<span className="font-semibold text-gray-200">verification</span> du dossier existant,
          {' '}<span className="font-semibold text-gray-200">archivage</span> sur le Drive,
          {' '}puis <span className="font-semibold text-gray-200">envoi</span> sur Git.
          {' '}Soyez patient pendant le traitement, surtout pour les <span className="font-semibold text-gray-200">gros assets</span> !
        </p>
      )}

      <SecretInput
        secret={secret}
        secretVisible={secretVisible}
        secretError={secretError}
        disabled={isUploading || isChecking}
        onChange={handleSecretChange}
        onToggleVisible={toggleSecretVisible}
      />

      {entries.length === 0 && (
        <div>
          <FolderDropzone
            isUploading={isUploading || isChecking}
            onFolderSelected={handleFolderSelected}
            onError={setGlobalError}
          />
        </div>
      )}

      {globalError && (
        <p className="text-xs text-red-400 text-center">{globalError}</p>
      )}

      {entries.length > 0 && (
        <div className="space-y-2">
          {entries.map((entry, i) => (
            <FolderCard
              key={i}
              entry={entry}
              index={i}
              onToggleViewer={handleToggleViewer}
              onRemove={removeEntry}
            />
          ))}
        </div>
      )}

      <ActionButtons
        isUploading={isUploading}
        isChecking={isChecking}
        isSecretEmpty={isSecretEmpty}
        hasPendingOrErrors={hasPendingOrErrors}
        allDone={allDone}
        hasErrors={hasErrors}
        onUpload={handleUpload}
        onCancel={handleCancel}
        onReset={handleReset}
      />

      {overwriteConfirm && (
        <OverwriteConfirmModal
          folderName={overwriteConfirm.folderName}
          diffs={overwriteConfirm.diffs}
          onCancel={handleOverwriteCancel}
          onConfirm={proceedUpload}
          disabled={isUploading || isChecking || isResolvingDriveError}
        />
      )}

      {noChangesFolder && (
        <NoChangesModal
          folderName={noChangesFolder}
          onCancel={() => {
            setNoChangesFolder(null)
            handleReset()
          }}
          onModify={() => setNoChangesFolder(null)}
        />
      )}

      {driveError && (
        <DriveErrorModal
          error={driveError.error}
          onCancel={handleDriveCancel}
          onContinue={handleDriveContinue}
          disabled={isResolvingDriveError}
        />
      )}
    </div>
  )
}
