import type { Request, Response } from 'express';
import { listAgentDentalKnowledgeAuditEntries, appendAgentDentalKnowledgeAuditEntry } from '../services/agent-dental-knowledge-audit.store';
import {
  appendAgentDentalKnowledgeVersion,
  findAgentDentalKnowledgeVersion,
  listAgentDentalKnowledgeVersions,
} from '../services/agent-dental-knowledge-version.store';
import {
  deleteAgentDentalKnowledgeArticle,
  listAgentDentalKnowledgeArticles,
  upsertAgentDentalKnowledgeArticle,
} from '../services/agent-dental-knowledge.store';
import type { StaffSessionUser } from '../middleware/staff-session.middleware';

const resolveRouteParam = (value: string | string[] | undefined) => (Array.isArray(value) ? value[0] : value);

export const getAgentDentalKnowledge = async (_req: Request, res: Response) => {
  try {
    const articles = await listAgentDentalKnowledgeArticles();
    res.setHeader('X-Data-Source', 'local-fallback');
    return res.json({ articles });
  } catch (error) {
    console.error('Error loading AgentDental knowledge articles:', error);
    return res.status(500).json({ error: 'No se pudo cargar la base de conocimiento del agente.' });
  }
};

export const getAgentDentalKnowledgeAudit = async (req: Request, res: Response) => {
  const limit =
    typeof req.query.limit === 'string' && Number.isFinite(Number(req.query.limit))
      ? Number(req.query.limit)
      : 12;

  try {
    const entries = await listAgentDentalKnowledgeAuditEntries(limit);
    res.setHeader('X-Data-Source', 'local-fallback');
    return res.json({ entries });
  } catch (error) {
    console.error('Error loading AgentDental knowledge audit entries:', error);
    return res.status(500).json({ error: 'No se pudo cargar la auditoria del agente.' });
  }
};

export const getAgentDentalKnowledgeVersions = async (req: Request, res: Response) => {
  const articleId = resolveRouteParam(req.params.articleId) ?? '';
  const limit =
    typeof req.query.limit === 'string' && Number.isFinite(Number(req.query.limit))
      ? Number(req.query.limit)
      : 12;

  if (!articleId) {
    return res.status(400).json({ error: 'Articulo invalido.' });
  }

  try {
    const versions = await listAgentDentalKnowledgeVersions(articleId, limit);
    res.setHeader('X-Data-Source', 'local-fallback');
    return res.json({ versions });
  } catch (error) {
    console.error('Error loading AgentDental knowledge versions:', error);
    return res.status(500).json({ error: 'No se pudo cargar el historial del articulo.' });
  }
};

export const postAgentDentalKnowledge = async (req: Request, res: Response) => {
  try {
    const actor = res.locals.staffUser as StaffSessionUser;
    const { article, action } = await upsertAgentDentalKnowledgeArticle(req.body ?? {});
    await appendAgentDentalKnowledgeVersion({
      articleId: article.id,
      articleTitle: article.title,
      action,
      actorUserId: actor.id,
      actorName: actor.name,
      actorRole: actor.role,
      snapshot: article,
    });
    await appendAgentDentalKnowledgeAuditEntry({
      articleId: article.id,
      articleTitle: article.title,
      action,
      actorUserId: actor.id,
      actorName: actor.name,
      actorRole: actor.role,
    });
    res.setHeader('X-Data-Source', 'local-fallback');
    return res.status(201).json({ article });
  } catch (error) {
    if (error instanceof Error && error.message === 'Articulo invalido') {
      return res.status(400).json({ error: 'Completa titulo, resumen, respuesta y audiencia del articulo.' });
    }

    console.error('Error saving AgentDental knowledge article:', error);
    return res.status(500).json({ error: 'No se pudo guardar el articulo del agente.' });
  }
};

export const removeAgentDentalKnowledge = async (req: Request, res: Response) => {
  try {
    const articleId = resolveRouteParam(req.params.articleId) ?? '';
    const actor = res.locals.staffUser as StaffSessionUser;
    const deleted = await deleteAgentDentalKnowledgeArticle(articleId);

    if (!deleted) {
      return res.status(404).json({ error: 'Articulo no encontrado.' });
    }

    await appendAgentDentalKnowledgeVersion({
      articleId: deleted.id,
      articleTitle: deleted.title,
      action: 'DELETED',
      actorUserId: actor.id,
      actorName: actor.name,
      actorRole: actor.role,
      snapshot: deleted,
    });
    await appendAgentDentalKnowledgeAuditEntry({
      articleId: deleted.id,
      articleTitle: deleted.title,
      action: 'DELETED',
      actorUserId: actor.id,
      actorName: actor.name,
      actorRole: actor.role,
    });

    res.setHeader('X-Data-Source', 'local-fallback');
    return res.status(204).send();
  } catch (error) {
    console.error('Error deleting AgentDental knowledge article:', error);
    return res.status(500).json({ error: 'No se pudo eliminar el articulo del agente.' });
  }
};

export const restoreAgentDentalKnowledgeVersion = async (req: Request, res: Response) => {
  const articleId = resolveRouteParam(req.params.articleId) ?? '';
  const versionId = resolveRouteParam(req.params.versionId) ?? '';

  if (!articleId || !versionId) {
    return res.status(400).json({ error: 'Version invalida.' });
  }

  try {
    const actor = res.locals.staffUser as StaffSessionUser;
    const version = await findAgentDentalKnowledgeVersion(articleId, versionId);

    if (!version) {
      return res.status(404).json({ error: 'Version no encontrada.' });
    }

    const { article } = await upsertAgentDentalKnowledgeArticle({
      ...version.snapshot,
      id: version.snapshot.id,
      createdAt: version.snapshot.createdAt,
      createdBy: version.snapshot.createdBy,
    });

    await appendAgentDentalKnowledgeVersion({
      articleId: article.id,
      articleTitle: article.title,
      action: 'RESTORED',
      actorUserId: actor.id,
      actorName: actor.name,
      actorRole: actor.role,
      snapshot: article,
    });
    await appendAgentDentalKnowledgeAuditEntry({
      articleId: article.id,
      articleTitle: article.title,
      action: 'RESTORED',
      actorUserId: actor.id,
      actorName: actor.name,
      actorRole: actor.role,
    });

    res.setHeader('X-Data-Source', 'local-fallback');
    return res.json({ article });
  } catch (error) {
    console.error('Error restoring AgentDental knowledge version:', error);
    return res.status(500).json({ error: 'No se pudo restaurar esta version del articulo.' });
  }
};
