import { useEffect, useRef, useState } from 'react';
import { FileUpload } from 'primereact/fileupload';
import { Button } from 'primereact/button';
import { Tag } from 'primereact/tag';
import { ProgressBar } from 'primereact/progressbar';
import { Toast } from 'primereact/toast';

function formatBytes(value) {
  const parsed = Number(value);
  if (!Number.isFinite(parsed) || parsed < 0) {
    return 'n/a';
  }
  if (parsed === 0) {
    return '0 B';
  }
  const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
  let unitIndex = 0;
  let current = parsed;
  while (current >= 1024 && unitIndex < units.length - 1) {
    current /= 1024;
    unitIndex += 1;
  }
  const digits = unitIndex <= 1 ? 0 : 2;
  return `${current.toFixed(digits)} ${units[unitIndex]}`;
}

function normalizeJobId(value) {
  const parsed = Number(value);
  if (!Number.isFinite(parsed) || parsed <= 0) {
    return null;
  }
  return Math.trunc(parsed);
}

export default function AudiobookUploadPanel({
  audiobookUpload,
  onAudiobookUpload,
  onUploaded = null
}) {
  const toastRef = useRef(null);
  const fileUploadRef = useRef(null);
  const [uploadFile, setUploadFile] = useState(null);
  const [statusVisible, setStatusVisible] = useState(false);

  const phase = String(audiobookUpload?.phase || 'idle').trim().toLowerCase();
  const uploadBusy = phase === 'uploading' || phase === 'processing';
  const progress = Number.isFinite(Number(audiobookUpload?.progressPercent))
    ? Math.max(0, Math.min(100, Number(audiobookUpload.progressPercent)))
    : 0;
  const loadedBytes = Number(audiobookUpload?.loadedBytes || 0);
  const totalBytes = Number(audiobookUpload?.totalBytes || 0);
  const fileName = String(audiobookUpload?.fileName || '').trim()
    || String(uploadFile?.name || '').trim()
    || null;
  const statusTone = phase === 'error'
    ? 'danger'
    : phase === 'completed'
      ? 'success'
      : phase === 'processing'
        ? 'info'
        : phase === 'uploading'
          ? 'warning'
          : 'secondary';
  const statusLabel = phase === 'uploading'
    ? 'Upload laeuft'
    : phase === 'processing'
      ? 'Server verarbeitet'
      : phase === 'completed'
        ? 'Bereit'
        : phase === 'error'
          ? 'Fehler'
          : 'Inaktiv';

  useEffect(() => {
    if (phase === 'idle') {
      setStatusVisible(false);
      return;
    }
    setStatusVisible(true);
    if (phase === 'completed') {
      const timer = setTimeout(() => setStatusVisible(false), 5000);
      return () => clearTimeout(timer);
    }
    return undefined;
  }, [phase]);

  const handleUpload = async () => {
    if (!uploadFile) {
      toastRef.current?.show({
        severity: 'warn',
        summary: 'Keine Datei',
        detail: 'Bitte zuerst eine AAX-Datei auswaehlen.',
        life: 2600
      });
      return;
    }
    try {
      const response = await onAudiobookUpload?.(uploadFile, { startImmediately: false });
      const uploadedJobId = normalizeJobId(response?.result?.jobId);
      if (uploadedJobId) {
        toastRef.current?.show({
          severity: 'success',
          summary: 'Audiobook importiert',
          detail: `Job #${uploadedJobId} ist bereit.`,
          life: 3200
        });
      } else {
        toastRef.current?.show({
          severity: 'success',
          summary: 'Audiobook importiert',
          detail: 'Upload abgeschlossen.',
          life: 2600
        });
      }
      setUploadFile(null);
      fileUploadRef.current?.clear?.();
      onUploaded?.(uploadedJobId, response);
    } catch (error) {
      toastRef.current?.show({
        severity: 'error',
        summary: 'Upload fehlgeschlagen',
        detail: error?.message || 'Bitte Logs pruefen.',
        life: 4200
      });
    }
  };

  return (
    <div className="audiobook-upload-panel">
      <Toast ref={toastRef} position="top-right" />
      <FileUpload
        ref={fileUploadRef}
        accept=".aax"
        maxFileSize={10737418240}
        customUpload
        uploadHandler={() => void handleUpload()}
        disabled={uploadBusy}
        onSelect={(event) => setUploadFile(event.files[0] || null)}
        onClear={() => setUploadFile(null)}
        onRemove={() => setUploadFile(null)}
        chooseOptions={{ icon: 'pi pi-images', iconOnly: true, className: 'p-button-rounded p-button-outlined' }}
        uploadOptions={{ icon: 'pi pi-cloud-upload', iconOnly: true, className: 'p-button-rounded p-button-outlined p-button-success' }}
        cancelOptions={{ icon: 'pi pi-times', iconOnly: true, className: 'p-button-rounded p-button-outlined p-button-danger' }}
        itemTemplate={(file, options) => (
          <div className="aax-file-item">
            <i className="pi pi-headphones aax-file-icon" />
            <div className="aax-file-info">
              <span className="aax-file-name" title={file.name}>{file.name}</span>
              <small>{options.formatSize}</small>
            </div>
            <Button
              icon="pi pi-times"
              text
              rounded
              severity="danger"
              size="small"
              onClick={options.onRemove}
              disabled={uploadBusy}
            />
          </div>
        )}
        emptyTemplate={() => (
          <div className="aax-drop-zone">
            <i className="pi pi-headphones aax-drop-icon" />
            <p>AAX-Datei hier ablegen</p>
            <small>oder oben "Auswaehlen" klicken</small>
          </div>
        )}
      />

      {statusVisible ? (
        <div className={`audiobook-upload-status tone-${statusTone}`}>
          <div className="audiobook-upload-status-head">
            <strong>{statusLabel}</strong>
            <Tag value={statusLabel} severity={statusTone} />
          </div>
          {audiobookUpload?.statusText ? <small>{audiobookUpload.statusText}</small> : null}
          {fileName ? (
            <small className="audiobook-upload-file" title={fileName}>
              Datei: {fileName}
            </small>
          ) : null}
          <div
            className="ripper-job-row-progress audiobook-upload-progress"
            aria-label={`Audiobook Upload ${Math.round(progress)} Prozent`}
          >
            <ProgressBar value={progress} showValue={false} />
            <small>
              {phase === 'processing'
                ? '100% | Upload fertig, Job wird vorbereitet ...'
                : totalBytes > 0
                  ? `${Math.round(progress)}% | ${formatBytes(loadedBytes)} / ${formatBytes(totalBytes)}`
                  : `${Math.round(progress)}%`}
            </small>
          </div>
        </div>
      ) : null}
    </div>
  );
}
