import { Router } from 'express';
import { db } from '../db/index.js';
import { publications } from '../db/schema.js';
import { desc, eq, and } from 'drizzle-orm';
import { blocksToSearchText } from '../lib/content.js';
import type { ContentBlock } from '../db/schema.js';

const router = Router();

function slugify(s: string): string {
  const slug = s
    .toLowerCase()
    .replace(/[^\p{L}\p{N}\s-]/gu, '')
    .replace(/\s+/g, '-')
    .replace(/-+/g, '-')
    .trim();
  return slug || `post-${Date.now()}`;
}

// Создать публикацию
router.post('/', (req, res) => {
  try {
    const {
      title,
      slug,
      excerpt,
      content,
      contentBlocks,
      previewImage,
      url,
      author,
      status,
      scheduledAt,
    } = req.body;

    if (!title || !url) {
      return res.status(400).json({ error: 'Необходимы поля: title, url' });
    }

    const finalSlug = slug || slugify(title);
    const pubStatus = status || 'draft';
    const now = new Date().toISOString();
    const blocks: ContentBlock[] =
      contentBlocks && Array.isArray(contentBlocks)
        ? contentBlocks
        : content
          ? [{ type: 'text', data: { html: content } }]
          : [];

    let publishedAt: string | null = null;
    if (pubStatus === 'published') publishedAt = now;
    if (pubStatus === 'scheduled' && scheduledAt) publishedAt = null;

    const result = db
      .insert(publications)
      .values({
        title,
        slug: finalSlug,
        excerpt: excerpt || (typeof content === 'string' ? content.slice(0, 300) : null),
        contentBlocks: blocks,
        previewImage: previewImage || null,
        url,
        author: author || null,
        status: pubStatus,
        publishedAt,
        scheduledAt: scheduledAt || null,
      })
      .run();

    res.status(201).json({ id: result.lastInsertRowid, message: 'Публикация создана' });
  } catch (e) {
    console.error(e);
    res.status(500).json({ error: 'Ошибка создания публикации' });
  }
});

// Список публикаций (с фильтрами)
router.get('/', (req, res) => {
  try {
    const q = req.query.q as string | undefined;
    const status = req.query.status as string | undefined;
    const limit = Math.min(parseInt(req.query.limit as string) || 50, 100);
    const offset = parseInt(req.query.offset as string) || 0;

    let baseQuery = db.select().from(publications).orderBy(desc(publications.createdAt));

    const conditions = [];
    if (status) {
      conditions.push(eq(publications.status, status as 'draft' | 'scheduled' | 'published'));
    }

    const whereClause = conditions.length ? and(...conditions) : undefined;
    const items = (whereClause
      ? baseQuery.where(whereClause)
      : baseQuery
    )
      .limit(limit)
      .offset(offset)
      .all();

    let result = items;
    if (q) {
      const qLower = q.toLowerCase();
      result = items.filter(
        (p) =>
          p.title?.toLowerCase().includes(qLower) ||
          (p.excerpt && p.excerpt.toLowerCase().includes(qLower)) ||
          p.url?.toLowerCase().includes(qLower) ||
          blocksToSearchText(p.contentBlocks).toLowerCase().includes(qLower),
      );
    }

    res.json({ publications: result });
  } catch (e) {
    console.error(e);
    res.status(500).json({ error: 'Ошибка получения публикаций' });
  }
});

// Календарь: публикации по датам (для редакторского календаря)
router.get('/calendar', (req, res) => {
  try {
    const year = parseInt(req.query.year as string) || new Date().getFullYear();
    const month = parseInt(req.query.month as string);

    const items = db
      .select({
        id: publications.id,
        title: publications.title,
        status: publications.status,
        scheduledAt: publications.scheduledAt,
        publishedAt: publications.publishedAt,
        createdAt: publications.createdAt,
      })
      .from(publications)
      .all();

    const byDate: Record<string, typeof items> = {};
    for (const p of items) {
      const dateStr =
        p.scheduledAt?.slice(0, 10) || p.publishedAt?.slice(0, 10) || p.createdAt?.slice(0, 10);
      if (!dateStr) continue;
      if (month !== undefined) {
        const [, m] = dateStr.split('-').map(Number);
        if (m !== month) continue;
      }
      const [y] = dateStr.split('-').map(Number);
      if (y !== year) continue;
      if (!byDate[dateStr]) byDate[dateStr] = [];
      byDate[dateStr].push(p);
    }

    res.json({ calendar: byDate });
  } catch (e) {
    console.error(e);
    res.status(500).json({ error: 'Ошибка календаря' });
  }
});

// Одна публикация по ID
router.get('/:id', (req, res) => {
  const id = parseInt(req.params.id);
  if (isNaN(id)) return res.status(400).json({ error: 'Неверный ID' });
  const row = db.select().from(publications).where(eq(publications.id, id)).get();
  if (!row) return res.status(404).json({ error: 'Публикация не найдена' });
  res.json(row);
});

// По slug
router.get('/slug/:slug', (req, res) => {
  const row = db
    .select()
    .from(publications)
    .where(eq(publications.slug, req.params.slug))
    .get();
  if (!row) return res.status(404).json({ error: 'Публикация не найдена' });
  res.json(row);
});

// Обновить
router.patch('/:id', (req, res) => {
  const id = parseInt(req.params.id);
  if (isNaN(id)) return res.status(400).json({ error: 'Неверный ID' });

  const {
    title,
    slug,
    excerpt,
    contentBlocks,
    previewImage,
    url,
    author,
    status,
    scheduledAt,
    publishedAt,
  } = req.body;

  const updates: Record<string, unknown> = {
    updatedAt: new Date().toISOString(),
  };
  if (title !== undefined) updates.title = title;
  if (slug !== undefined) updates.slug = slug;
  if (excerpt !== undefined) updates.excerpt = excerpt;
  if (contentBlocks !== undefined) updates.contentBlocks = contentBlocks;
  if (previewImage !== undefined) updates.previewImage = previewImage;
  if (url !== undefined) updates.url = url;
  if (author !== undefined) updates.author = author;
  if (status !== undefined) updates.status = status;
  if (scheduledAt !== undefined) updates.scheduledAt = scheduledAt;
  if (publishedAt !== undefined) updates.publishedAt = publishedAt;

  const result = db.update(publications).set(updates as any).where(eq(publications.id, id)).run();
  if (result.changes === 0) return res.status(404).json({ error: 'Публикация не найдена' });
  res.json({ message: 'Публикация обновлена' });
});

// Удалить
router.delete('/:id', (req, res) => {
  const id = parseInt(req.params.id);
  if (isNaN(id)) return res.status(400).json({ error: 'Неверный ID' });
  const result = db.delete(publications).where(eq(publications.id, id)).run();
  if (result.changes === 0) return res.status(404).json({ error: 'Публикация не найдена' });
  res.json({ message: 'Публикация удалена' });
});

export default router;
