import { useEffect, useState } from "react";
import { FileText, Trash2, BarChart3, Database, AlertCircle } from "lucide-react";
import type { EmbedStore } from "../editor/embeds/embed-store";
import type { EmbedDataFileMeta } from "../editor/embeds/embed-data-store";
import { UploadZone } from "./UploadZone";
import { formatBytes } from "../utils/data-files";
import type { UploadResult } from "../hooks/useEmbedData";

interface FilesSidebarProps {
  embedStore: EmbedStore | null;
  currentSrc: string;
  dataFiles: EmbedDataFileMeta[];
  selectedDataFile: string | null;
  onSelectDataFile: (name: string | null) => void;
  onUploadFiles: (files: FileList | File[]) => Promise<UploadResult[]>;
  onRemoveDataFile: (name: string) => void;
}

export function FilesSidebar({
  embedStore,
  currentSrc,
  dataFiles,
  selectedDataFile,
  onSelectDataFile,
  onUploadFiles,
  onRemoveDataFile,
}: FilesSidebarProps) {
  const [charts, setCharts] = useState<string[]>(() =>
    embedStore ? embedStore.keys() : [],
  );
  const [uploadError, setUploadError] = useState<string | null>(null);

  useEffect(() => {
    if (!embedStore) return;
    setCharts(embedStore.keys());
    return embedStore.observe(() => setCharts(embedStore.keys()));
  }, [embedStore]);

  const handleUpload = async (files: FileList | File[]) => {
    setUploadError(null);
    const results = await onUploadFiles(files);
    const firstError = results.find((r) => !r.ok);
    if (firstError?.error) setUploadError(firstError.error);
    const firstOk = results.find((r) => r.ok && r.name);
    if (firstOk?.name) onSelectDataFile(firstOk.name);
  };

  return (
    <div className="es-files">
      <section className="es-files__section">
        <header className="es-files__section-title">
          <BarChart3 size={13} />
          <span>Charts</span>
          <span className="es-files__count">{charts.length}</span>
        </header>
        <ul className="es-files__list">
          {charts.length === 0 && (
            <li className="es-files__empty">No charts yet</li>
          )}
          {charts.map((name) => (
            <li
              key={name}
              className={`es-files__item ${name === currentSrc ? "es-files__item--current" : ""}`}
              title={name === currentSrc ? "Current chart" : name}
            >
              <FileText size={12} />
              <span className="es-files__name">{name}</span>
              {name === currentSrc && (
                <span className="es-files__badge">editing</span>
              )}
            </li>
          ))}
        </ul>
      </section>

      <section className="es-files__section">
        <header className="es-files__section-title">
          <Database size={13} />
          <span>Data</span>
          <span className="es-files__count">{dataFiles.length}</span>
        </header>

        <ul className="es-files__list">
          {dataFiles.length === 0 && (
            <li className="es-files__empty">No data uploaded yet</li>
          )}
          {dataFiles.map((file) => {
            const isSelected = file.name === selectedDataFile;
            return (
              <li
                key={file.name}
                className={`es-files__item es-files__item--data ${isSelected ? "es-files__item--current" : ""}`}
              >
                <button
                  type="button"
                  className="es-files__item-main"
                  onClick={() => onSelectDataFile(isSelected ? null : file.name)}
                  title={file.name}
                >
                  <FileText size={12} />
                  <span className="es-files__name">{file.name}</span>
                  <span className="es-files__size">{formatBytes(file.size)}</span>
                </button>
                <button
                  type="button"
                  className="es-files__item-remove"
                  onClick={(e) => {
                    e.stopPropagation();
                    if (isSelected) onSelectDataFile(null);
                    onRemoveDataFile(file.name);
                  }}
                  aria-label={`Remove ${file.name}`}
                  title="Remove file"
                >
                  <Trash2 size={12} />
                </button>
              </li>
            );
          })}
        </ul>

        <UploadZone onFiles={handleUpload} compact={dataFiles.length > 0} />
        {uploadError && (
          <div className="es-files__error">
            <AlertCircle size={12} />
            <span>{uploadError}</span>
          </div>
        )}
      </section>
    </div>
  );
}
