'use client';
import React, {useCallback, useEffect, useState} from 'react';
import Link from 'next/link';
import {useTranslations} from 'next-intl';
import {useAuth} from '@/contexts/AuthContext';
import {
  createAnnonce,
  deleteAnnonce,
  getAnnonces,
  getAnnonceTypes,
  repondreAnnonce,
  updateAnnonce,
  type Annonce,
  type AnnonceType,
} from '@/services/annonceService';
import './AnnoncesBoard.css';

interface AnnoncesBoardProps {
  locale: string;
}

interface Saisie {
  titre: string;
  texte: string;
  typeId: number;
}

/**
 * Petites annonces (spec L187-L193) : liste par catégorie, dépôt / modification / suppression par
 * le membre connecté, réponse transmise par email à l'annonceur, invitation à se connecter sinon.
 */
export default function AnnoncesBoard({locale}: AnnoncesBoardProps) {
  const t = useTranslations('Annonces');
  const {isAuthenticated, user} = useAuth();
  const [types, setTypes] = useState<AnnonceType[]>([]);
  const [annonces, setAnnonces] = useState<Annonce[]>([]);
  const [typeFiltre, setTypeFiltre] = useState<number | undefined>(undefined);
  const [chargement, setChargement] = useState(true);
  const [erreur, setErreur] = useState<'error_load' | 'error_create' | 'error_update' | 'error_delete' | null>(null);
  const [nouvelle, setNouvelle] = useState<Saisie | null>(null);
  const [enEdition, setEnEdition] = useState<{id: number; saisie: Saisie} | null>(null);
  const [reponse, setReponse] = useState<{id: number; message: string; envoyee: boolean; erreur: boolean} | null>(null);
  const connexion = `/${locale}/connexion`;

  const charger = useCallback(async (typeId?: number) => {
    setChargement(true);
    setErreur(null);
    try {
      setAnnonces(await getAnnonces(typeId));
    } catch {
      setErreur('error_load');
    } finally {
      setChargement(false);
    }
  }, []);

  useEffect(() => {
    getAnnonceTypes().then(setTypes).catch(() => setTypes([]));
  }, []);

  useEffect(() => {
    charger(typeFiltre);
  }, [charger, typeFiltre]);

  const estProprietaire = (annonce: Annonce) => isAuthenticated && !!user?.username && user.username === annonce.auteur?.pseudo;
  const nomType = (typeId: number) => types.find((type) => type.id === typeId)?.titre;

  const publier = async (event: React.FormEvent) => {
    event.preventDefault();
    if (!nouvelle || !nouvelle.titre.trim() || !nouvelle.typeId) return;
    try {
      const creee = await createAnnonce({titre: nouvelle.titre.trim(), texte: nouvelle.texte.trim(), typeId: nouvelle.typeId});
      setAnnonces((liste) => [creee, ...liste]);
      setNouvelle(null);
    } catch {
      setErreur('error_create');
    }
  };

  const enregistrer = async (event: React.FormEvent) => {
    event.preventDefault();
    if (!enEdition || !enEdition.saisie.titre.trim()) return;
    try {
      const modifiee = await updateAnnonce(enEdition.id, {
        titre: enEdition.saisie.titre.trim(),
        texte: enEdition.saisie.texte.trim(),
        typeId: enEdition.saisie.typeId,
      });
      setAnnonces((liste) => liste.map((a) => (a.id === modifiee.id ? modifiee : a)));
      setEnEdition(null);
    } catch {
      setErreur('error_update');
    }
  };

  const supprimer = async (id: number) => {
    if (!window.confirm(t('delete_confirm'))) return;
    try {
      await deleteAnnonce(id);
      setAnnonces((liste) => liste.filter((a) => a.id !== id));
    } catch {
      setErreur('error_delete');
    }
  };

  const envoyerReponse = async (event: React.FormEvent) => {
    event.preventDefault();
    if (!reponse || !reponse.message.trim()) return;
    try {
      await repondreAnnonce(reponse.id, reponse.message.trim());
      setReponse({...reponse, envoyee: true, erreur: false});
    } catch {
      setReponse({...reponse, erreur: true});
    }
  };

  const formulaire = (saisie: Saisie, onChange: (s: Saisie) => void, onSubmit: (e: React.FormEvent) => void, onCancel: () => void, libelleBouton: string, prefixe: string) => (
    <form onSubmit={onSubmit} className="tk-annonce-form" data-testid={`${prefixe}-form`}>
      <div className="mb-2">
        <label className="form-label" htmlFor={`${prefixe}-titre`}>{t('titre')}</label>
        <input id={`${prefixe}-titre`} className="form-control" value={saisie.titre} placeholder={t('titre_placeholder')} onChange={(e) => onChange({...saisie, titre: e.target.value})} required />
      </div>
      <div className="mb-2">
        <label className="form-label" htmlFor={`${prefixe}-texte`}>{t('texte')}</label>
        <textarea id={`${prefixe}-texte`} className="form-control" value={saisie.texte} placeholder={t('texte_placeholder')} onChange={(e) => onChange({...saisie, texte: e.target.value})} />
      </div>
      <div className="mb-3">
        <label className="form-label" htmlFor={`${prefixe}-type`}>{t('type')}</label>
        <select id={`${prefixe}-type`} className="form-select" value={saisie.typeId} onChange={(e) => onChange({...saisie, typeId: Number(e.target.value)})}>
          {types.map((type) => (
            <option key={type.id} value={type.id}>{type.titre}</option>
          ))}
        </select>
      </div>
      <div className="d-flex gap-2">
        <button type="submit" className="btn btn-primary btn-sm">{libelleBouton}</button>
        <button type="button" className="btn btn-outline-secondary btn-sm" onClick={onCancel}>{t('cancel')}</button>
      </div>
    </form>
  );

  return (
    <div className="tk-annonces">
      <div className="tk-annonces__filtres" role="group" aria-label={t('type')}>
        <button type="button" className={`btn btn-sm ${typeFiltre === undefined ? 'btn-primary' : 'btn-outline-primary'}`} onClick={() => setTypeFiltre(undefined)}>
          {t('all_types')}
        </button>
        {types.map((type) => (
          <button key={type.id} type="button" className={`btn btn-sm ${typeFiltre === type.id ? 'btn-primary' : 'btn-outline-primary'}`} onClick={() => setTypeFiltre(type.id)} title={type.soustitre}>
            {type.titre}
          </button>
        ))}
      </div>

      <div className="tk-annonces__depot">
        {isAuthenticated ? (
          nouvelle ? (
            formulaire(nouvelle, setNouvelle, publier, () => setNouvelle(null), t('submit'), 'annonce')
          ) : (
            <button type="button" className="btn btn-primary" onClick={() => setNouvelle({titre: '', texte: '', typeId: types[0]?.id ?? 1})}>
              {t('create')}
            </button>
          )
        ) : (
          <Link href={connexion} className="btn btn-outline-primary">{t('login_to_post')}</Link>
        )}
      </div>

      {erreur && <div role="alert" className="alert alert-danger">{t(erreur)}</div>}

      {chargement ? (
        <p className="text-muted">…</p>
      ) : annonces.length === 0 ? (
        <p className="text-muted tk-annonces__vide">{t('empty')}</p>
      ) : (
        <ul className="tk-annonces__liste">
          {annonces.map((annonce) => (
            <li key={annonce.id}>
              <article className={`tk-annonce${estProprietaire(annonce) ? ' tk-annonce--mienne' : ''}`}>
                {enEdition?.id === annonce.id ? (
                  formulaire(enEdition.saisie, (saisie) => setEnEdition({id: annonce.id, saisie}), enregistrer, () => setEnEdition(null), t('save'), `annonce-${annonce.id}`)
                ) : (
                  <>
                    <header className="tk-annonce__entete">
                      {nomType(annonce.typeId) && <span className="tk-annonce__type">{nomType(annonce.typeId)}</span>}
                      <h3 className="tk-annonce__titre">{annonce.titre}</h3>
                      <p className="tk-annonce__meta text-muted small mb-0">
                        {annonce.auteur?.pseudo}
                        {annonce.date && <> · {t('published_on', {date: annonce.date})}</>}
                        {estProprietaire(annonce) && <> · <strong>{t('your_ad')}</strong></>}
                      </p>
                    </header>
                    {annonce.texte && <p className="tk-annonce__texte">{annonce.texte}</p>}
                    <footer className="tk-annonce__actions">
                      {estProprietaire(annonce) ? (
                        <>
                          <button type="button" className="btn btn-outline-secondary btn-sm" onClick={() => setEnEdition({id: annonce.id, saisie: {titre: annonce.titre, texte: annonce.texte ?? '', typeId: annonce.typeId}})}>
                            {t('edit')}
                          </button>
                          <button type="button" className="btn btn-outline-danger btn-sm" onClick={() => supprimer(annonce.id)}>{t('delete')}</button>
                        </>
                      ) : isAuthenticated ? (
                        reponse?.id === annonce.id ? (
                          reponse.envoyee ? (
                            <p className="tk-annonce__reponse-ok text-success mb-0" role="status">{t('reply_sent')}</p>
                          ) : (
                            <form onSubmit={envoyerReponse} className="tk-annonce__reponse w-100">
                              <textarea className="form-control mb-2" placeholder={t('reply_placeholder')} value={reponse.message} onChange={(e) => setReponse({...reponse, message: e.target.value})} required />
                              {reponse.erreur && <p className="text-danger small">{t('reply_error')}</p>}
                              <div className="d-flex gap-2">
                                <button type="submit" className="btn btn-primary btn-sm">{t('reply_send')}</button>
                                <button type="button" className="btn btn-outline-secondary btn-sm" onClick={() => setReponse(null)}>{t('cancel')}</button>
                              </div>
                            </form>
                          )
                        ) : (
                          <button type="button" className="btn btn-primary btn-sm" onClick={() => setReponse({id: annonce.id, message: '', envoyee: false, erreur: false})}>{t('reply')}</button>
                        )
                      ) : (
                        <Link href={connexion} className="tk-annonce__connexion">{t('login_to_reply')}</Link>
                      )}
                    </footer>
                  </>
                )}
              </article>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}
