import { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { api, type TourSummary } from '../api/client';
import type { Painting } from '../types';
import './ToursPage.css';

interface Props {
  onBack: () => void;
}

interface StopDraft {
  paintingId: number;
  title: string;
  artistName: string;
  year: number | null;
  thumbnailPath: string | null;
  body: string;
}

export default function ToursPage({ onBack }: Props) {
  const { t } = useTranslation('tours');
  const [tours, setTours] = useState<TourSummary[]>([]);
  const [selectedId, setSelectedId] = useState<number | null>(null);
  const [title, setTitle] = useState('');
  const [description, setDescription] = useState('');
  const [status, setStatus] = useState<'draft' | 'published'>('draft');
  const [stops, setStops] = useState<StopDraft[]>([]);
  const [searchQ, setSearchQ] = useState('');
  const [searchHits, setSearchHits] = useState<
    Array<{ id: number; title: string; artistName: string; year: number | null; thumbnailPath: string | null }>
  >([]);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [newTitle, setNewTitle] = useState('');

  const loadList = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const data = await api.listAdminTours();
      setTours(data.tours);
    } catch (err) {
      setError(err instanceof Error ? err.message : t('loadFailed'));
    } finally {
      setLoading(false);
    }
  }, [t]);

  useEffect(() => {
    void loadList();
  }, [loadList]);

  const openTour = async (id: number) => {
    setSelectedId(id);
    setError(null);
    try {
      const data = await api.getTour(id);
      setTitle(data.tour.title);
      setDescription(data.tour.description || '');
      setStatus(data.tour.status);
      setStops(
        data.paintings.map((p: Painting) => ({
          paintingId: p.id,
          title: p.title,
          artistName: p.artist_name || '',
          year: p.year ?? null,
          thumbnailPath: p.thumbnail_path || null,
          body: data.stopBodies[p.id] || '',
        })),
      );
    } catch (err) {
      setError(err instanceof Error ? err.message : t('loadFailed'));
    }
  };

  useEffect(() => {
    const handle = setTimeout(() => {
      void (async () => {
        if (searchQ.trim().length < 2) {
          setSearchHits([]);
          return;
        }
        try {
          const data = await api.search(searchQ.trim(), { types: 'painting', limit: 12 });
          setSearchHits(
            data.results
              .filter((r) => r.type === 'painting')
              .map((r) => ({
                id: r.id,
                title: r.title,
                artistName: r.artist_name,
                year: r.year,
                thumbnailPath: r.thumbnail_path,
              })),
          );
        } catch {
          setSearchHits([]);
        }
      })();
    }, 250);
    return () => clearTimeout(handle);
  }, [searchQ]);

  const createTour = async () => {
    const name = newTitle.trim();
    if (!name) return;
    setSaving(true);
    setError(null);
    try {
      const { tour } = await api.createTour({ title: name, status: 'draft' });
      setNewTitle('');
      await loadList();
      await openTour(tour.id);
    } catch (err) {
      setError(err instanceof Error ? err.message : t('loadFailed'));
    } finally {
      setSaving(false);
    }
  };

  const saveMeta = async () => {
    if (!selectedId) return;
    setSaving(true);
    setError(null);
    try {
      await api.updateTour(selectedId, {
        title: title.trim(),
        description,
        status,
        coverPaintingId: stops[0]?.paintingId ?? null,
      });
      await loadList();
    } catch (err) {
      setError(err instanceof Error ? err.message : t('loadFailed'));
    } finally {
      setSaving(false);
    }
  };

  const saveStops = async () => {
    if (!selectedId) return;
    setSaving(true);
    setError(null);
    try {
      await api.saveTourStops(
        selectedId,
        stops.map((s) => ({ paintingId: s.paintingId, body: s.body })),
      );
      await api.updateTour(selectedId, {
        coverPaintingId: stops[0]?.paintingId ?? null,
      });
      await loadList();
    } catch (err) {
      setError(err instanceof Error ? err.message : t('loadFailed'));
    } finally {
      setSaving(false);
    }
  };

  const deleteTour = async () => {
    if (!selectedId) return;
    if (!window.confirm(t('confirmDelete'))) return;
    setSaving(true);
    try {
      await api.deleteTour(selectedId);
      setSelectedId(null);
      setStops([]);
      await loadList();
    } catch (err) {
      setError(err instanceof Error ? err.message : t('loadFailed'));
    } finally {
      setSaving(false);
    }
  };

  const addStop = (hit: {
    id: number;
    title: string;
    artistName: string;
    year: number | null;
    thumbnailPath: string | null;
  }) => {
    if (stops.some((s) => s.paintingId === hit.id)) return;
    setStops((prev) => [
      ...prev,
      {
        paintingId: hit.id,
        title: hit.title,
        artistName: hit.artistName,
        year: hit.year,
        thumbnailPath: hit.thumbnailPath,
        body: '',
      },
    ]);
    setSearchQ('');
    setSearchHits([]);
  };

  const moveStop = (index: number, dir: -1 | 1) => {
    const next = index + dir;
    if (next < 0 || next >= stops.length) return;
    setStops((prev) => {
      const copy = [...prev];
      const tmp = copy[index];
      copy[index] = copy[next];
      copy[next] = tmp;
      return copy;
    });
  };

  return (
    <div className="tours-page">
      <header className="tours-header">
        <button type="button" className="tours-back" onClick={onBack}>
          {t('back')}
        </button>
        <h1>{t('title')}</h1>
      </header>

      {error && <div className="tours-error">{error}</div>}

      <div className="tours-layout">
        <aside className="tours-list-panel">
          <div className="tours-create">
            <input
              value={newTitle}
              onChange={(e) => setNewTitle(e.target.value)}
              placeholder={t('newTourPlaceholder')}
            />
            <button type="button" disabled={saving || !newTitle.trim()} onClick={() => void createTour()}>
              {t('create')}
            </button>
          </div>
          {loading ? (
            <p className="muted">{t('loading')}</p>
          ) : (
            <ul className="tours-list">
              {tours.map((tour) => (
                <li key={tour.id}>
                  <button
                    type="button"
                    className={selectedId === tour.id ? 'active' : ''}
                    onClick={() => void openTour(tour.id)}
                  >
                    <strong>{tour.title}</strong>
                    <span className="muted">
                      {tour.status} · {t('stopCount', { count: tour.stopCount })}
                    </span>
                  </button>
                </li>
              ))}
              {tours.length === 0 && <li className="muted">{t('noTours')}</li>}
            </ul>
          )}
        </aside>

        <section className="tours-editor">
          {!selectedId ? (
            <p className="muted">{t('selectTour')}</p>
          ) : (
            <>
              <div className="tours-meta">
                <label>
                  {t('tourTitle')}
                  <input value={title} onChange={(e) => setTitle(e.target.value)} />
                </label>
                <label>
                  {t('tourDescription')}
                  <textarea value={description} onChange={(e) => setDescription(e.target.value)} rows={3} />
                </label>
                <label>
                  {t('status')}
                  <select
                    value={status}
                    onChange={(e) => setStatus(e.target.value as 'draft' | 'published')}
                  >
                    <option value="draft">{t('draft')}</option>
                    <option value="published">{t('published')}</option>
                  </select>
                </label>
                <div className="tours-meta-actions">
                  <button type="button" disabled={saving} onClick={() => void saveMeta()}>
                    {t('saveMeta')}
                  </button>
                  <button type="button" className="danger" disabled={saving} onClick={() => void deleteTour()}>
                    {t('delete')}
                  </button>
                </div>
              </div>

              <div className="tours-stops-toolbar">
                <input
                  type="search"
                  value={searchQ}
                  onChange={(e) => setSearchQ(e.target.value)}
                  placeholder={t('searchPainting')}
                />
                <button type="button" disabled={saving} onClick={() => void saveStops()}>
                  {t('saveStops')}
                </button>
              </div>
              {searchHits.length > 0 && (
                <ul className="tours-hits">
                  {searchHits.map((h) => (
                    <li key={h.id}>
                      <button type="button" onClick={() => addStop(h)}>
                        {h.artistName} — {h.title}
                      </button>
                    </li>
                  ))}
                </ul>
              )}

              <ol className="tours-stops">
                {stops.map((stop, index) => (
                  <li key={stop.paintingId}>
                    <div className="tours-stop-head">
                      <span>
                        {index + 1}. {stop.artistName} — {stop.title}
                        {stop.year != null ? ` (${stop.year})` : ''}
                      </span>
                      <div className="tours-stop-move">
                        <button type="button" onClick={() => moveStop(index, -1)} disabled={index === 0}>
                          ↑
                        </button>
                        <button
                          type="button"
                          onClick={() => moveStop(index, 1)}
                          disabled={index === stops.length - 1}
                        >
                          ↓
                        </button>
                        <button
                          type="button"
                          className="danger"
                          onClick={() => setStops((prev) => prev.filter((_, i) => i !== index))}
                        >
                          {t('remove')}
                        </button>
                      </div>
                    </div>
                    <textarea
                      value={stop.body}
                      onChange={(e) =>
                        setStops((prev) =>
                          prev.map((s, i) => (i === index ? { ...s, body: e.target.value } : s)),
                        )
                      }
                      rows={4}
                      placeholder={t('stopBodyPlaceholder')}
                    />
                  </li>
                ))}
                {stops.length === 0 && <li className="muted">{t('noStops')}</li>}
              </ol>
            </>
          )}
        </section>
      </div>
    </div>
  );
}
