'use client';

import React, { useCallback, useEffect, useRef, useState } from 'react';
import toast from 'react-hot-toast';
import { FiUploadCloud, FiTrash2, FiArrowLeft, FiArrowRight } from 'react-icons/fi';
import {
  listReportImages, uploadReportImages, updateReportImage, deleteReportImage, reorderReportImages,
  fetchReportImageBlob, type ReportImage,
} from '@/lib/api/audit-report-builder.api';

interface Props {
  reportId: number;
  canEdit: boolean;
  /** org_brief | audit_brief | clause */
  sectionKey: string;
  clauseId?: number;
  /** tells the parent how many pictures there are (for badges) */
  onCount?: (n: number) => void;
}

const MAX_MB = 8;

export default function ImagesManager({ reportId, canEdit, sectionKey, clauseId, onCount }: Props) {
  const [items, setItems] = useState<ReportImage[]>([]);
  const [thumbs, setThumbs] = useState<Record<number, string>>({});
  const [loading, setLoading] = useState(true);
  const [busy, setBusy] = useState(false);
  const [over, setOver] = useState(false);
  const input = useRef<HTMLInputElement>(null);
  const urls = useRef<string[]>([]);

  const load = useCallback(async () => {
    try {
      const rows = await listReportImages(reportId, clauseId ? { clause_id: clauseId } : { section_key: sectionKey });
      const mine = clauseId ? rows : rows.filter((r) => !r.clause_id);
      setItems(mine);
      onCount?.(mine.length);
    } catch (e: any) {
      toast.error(e.message || 'Could not load the pictures');
    } finally {
      setLoading(false);
    }
  }, [reportId, sectionKey, clauseId, onCount]);

  useEffect(() => {
    load();
  }, [load]);

  // thumbnails need the login token, so they are fetched as blobs
  useEffect(() => {
    let cancelled = false;
    items.forEach((it) => {
      if (thumbs[it.id]) return;
      fetchReportImageBlob(reportId, it.id)
        .then((b) => {
          if (cancelled) return;
          const u = URL.createObjectURL(b);
          urls.current.push(u);
          setThumbs((p) => ({ ...p, [it.id]: u }));
        })
        .catch(() => undefined);
    });
    return () => { cancelled = true; };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [items, reportId]);

  useEffect(() => () => urls.current.forEach((u) => URL.revokeObjectURL(u)), []);

  const send = async (list: File[]) => {
    const ok: File[] = [];
    for (const f of list) {
      if (!/^image\/(jpeg|png)$/i.test(f.type)) { toast.error(`"${f.name}" is not a JPG or PNG picture.`); continue; }
      if (f.size > MAX_MB * 1024 * 1024) { toast.error(`"${f.name}" is larger than ${MAX_MB} MB.`); continue; }
      ok.push(f);
    }
    if (!ok.length) return;
    setBusy(true);
    try {
      const saved = await uploadReportImages(reportId, ok, { section_key: sectionKey, clause_id: clauseId });
      setItems((p) => { const n = [...p, ...saved]; onCount?.(n.length); return n; });
      toast.success(`${saved.length} picture(s) added`);
    } catch (e: any) {
      toast.error(e.message || 'Upload failed');
    } finally {
      setBusy(false);
      if (input.current) input.current.value = '';
    }
  };

  const saveCaption = async (it: ReportImage, caption: string) => {
    if (caption === it.caption) return;
    try {
      await updateReportImage(reportId, it.id, { caption });
      setItems((p) => p.map((x) => (x.id === it.id ? { ...x, caption } : x)));
    } catch (e: any) {
      toast.error(e.message || 'Could not save the caption');
    }
  };

  const move = async (idx: number, dir: -1 | 1) => {
    const to = idx + dir;
    if (to < 0 || to >= items.length) return;
    const next = [...items];
    [next[idx], next[to]] = [next[to], next[idx]];
    setItems(next);
    try {
      await reorderReportImages(reportId, next.map((x) => x.id));
    } catch (e: any) {
      toast.error(e.message || 'Could not change the order');
      load();
    }
  };

  const remove = async (it: ReportImage) => {
    if (!window.confirm('Remove this picture from the report?')) return;
    try {
      await deleteReportImage(reportId, it.id);
      setItems((p) => { const n = p.filter((x) => x.id !== it.id); onCount?.(n.length); return n; });
    } catch (e: any) {
      toast.error(e.message || 'Could not remove the picture');
    }
  };

  return (
    <div>
      {canEdit && (
        <div
          className={`rb-drop${over ? ' is-over' : ''}`}
          onClick={() => input.current?.click()}
          onDragOver={(e) => { e.preventDefault(); setOver(true); }}
          onDragLeave={() => setOver(false)}
          onDrop={(e) => { e.preventDefault(); setOver(false); send(Array.from(e.dataTransfer.files)); }}
        >
          <FiUploadCloud size={20} />
          <div style={{ marginTop: 4 }}>
            {busy ? 'Uploading…' : <>Drop pictures here or <strong>click to choose</strong> (JPG / PNG, up to {MAX_MB} MB each, several at once)</>}
          </div>
          <input ref={input} type="file" accept="image/jpeg,image/png" multiple hidden onChange={(e) => send(Array.from(e.target.files ?? []))} />
        </div>
      )}

      {loading ? (
        <div className="rb-empty">Loading pictures…</div>
      ) : items.length === 0 ? (
        <div className="rb-empty">No pictures yet.</div>
      ) : (
        <div className="rb-photo-grid">
          {items.map((it, i) => (
            <div className="rb-photo" key={it.id}>
              <div className="rb-photo-img">
                {thumbs[it.id] ? <img src={thumbs[it.id]} alt={it.caption || it.original_name} /> : <span className="rb-hint">loading…</span>}
              </div>
              <div className="rb-photo-body">
                <input
                  className="rb-input"
                  defaultValue={it.caption}
                  disabled={!canEdit}
                  placeholder="Caption (printed under the picture)"
                  maxLength={300}
                  onBlur={(e) => saveCaption(it, e.target.value.trim())}
                />
                <div className="rb-photo-meta" title={it.original_name}>{it.original_name} · {Math.round(it.size_bytes / 1024)} KB</div>
                {canEdit && (
                  <div className="rb-photo-actions">
                    <span>
                      <button className="rb-btn rb-btn-sm" disabled={i === 0} onClick={() => move(i, -1)} title="Move earlier"><FiArrowLeft size={12} /></button>{' '}
                      <button className="rb-btn rb-btn-sm" disabled={i === items.length - 1} onClick={() => move(i, 1)} title="Move later"><FiArrowRight size={12} /></button>
                    </span>
                    <button className="rb-btn rb-btn-red rb-btn-sm" onClick={() => remove(it)} title="Remove"><FiTrash2 size={12} /></button>
                  </div>
                )}
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}
