import BlogService from '../services/blogService.js';
import SocialNetworkService from '../services/socialnetworkService.js';

const blogService = new BlogService();
const socialService = new SocialNetworkService();

export const createBlog = async (req, res) => {
  try {
    const { userid } = req.headers; // creator must be logged in
    const blog = await blogService.createBlog(userid, req.body || {});
    res.json(blog);
  } catch (e) {
    res.status(e.status || 400).json({ error: e.message });
  }
};

export const updateBlog = async (req, res) => {
  try {
    const { userid } = req.headers;
    const { id } = req.params;
    const blog = await blogService.updateBlog(userid, id, req.body || {});
    res.json(blog);
  } catch (e) {
    res.status(e.status || 400).json({ error: e.message });
  }
};

export const listBlogs = async (req, res) => {
  try {
    const { userid } = req.headers; // optional for access checks
    const blogs = await blogService.listBlogsForViewer(userid || null);
    res.json(blogs);
  } catch (e) {
    res.status(400).json({ error: e.message });
  }
};

export const getBlog = async (req, res) => {
  try {
    const { userid } = req.headers;
    const { id } = req.params;
    const blog = await blogService.getBlog(id, userid || null);
    res.json(blog);
  } catch (e) {
    res.status(e.status || 404).json({ error: e.message });
  }
};

export const createPost = async (req, res) => {
  try {
    const { userid } = req.headers;
    const { id } = req.params;
    const post = await blogService.createPost(userid, id, req.body || {});
    res.json(post);
  } catch (e) {
    res.status(e.status || 400).json({ error: e.message });
  }
};

export const listPosts = async (req, res) => {
  try {
    const { userid } = req.headers;
    const { id } = req.params;
    const page = Math.max(1, parseInt(req.query.page || '1', 10));
    const pageSize = Math.min(50, Math.max(1, parseInt(req.query.pageSize || '10', 10)));
    const all = await blogService.listPosts(id, userid || null);
    const total = all.length;
    const start = (page - 1) * pageSize;
    const posts = all.slice(start, start + pageSize);
    res.json({ items: posts, page, pageSize, total });
  } catch (e) {
    res.status(e.status || 400).json({ error: e.message });
  }
};

export const listBlogImages = async (req, res) => {
  try {
    const { userid } = req.headers;
    const user = await blogService.getUserByHashedId(userid);
    const blogFolder = await blogService.ensureBlogFolder(user.id);
    const images = await socialService.getFolderImageList(userid, blogFolder.id);
    res.json({ folderId: blogFolder.id, images });
  } catch (e) {
    res.status(400).json({ error: e.message });
  }
};

export const uploadBlogImage = async (req, res) => {
  try {
    const { userid } = req.headers;
    const user = await blogService.getUserByHashedId(userid);
    const blogFolder = await blogService.ensureBlogFolder(user.id);
    // Default visibility mirrors blog folder visibilities (already applied)
    const formData = {
      title: req.body?.title || 'Blog Image',
      description: req.body?.description || '',
      folderId: blogFolder.id,
      visibility: JSON.stringify([])
    };
    const file = req.file;
    const image = await socialService.uploadImage(userid, file, formData);
    res.status(201).json(image);
  } catch (e) {
    res.status(400).json({ error: e.message });
  }
};

export const getPublicBlogImageByHash = async (req, res) => {
  try {
    const { hash } = req.params;
    const filePath = await socialService.getImageFilePathPublicByHash(hash);
    res.sendFile(filePath, err => {
      if (err) {
        console.error('Error sending file:', err);
        res.status(500).json({ error: 'Error sending file' });
      }
    });
  } catch (e) {
    res.status(e.status || 403).json({ error: e.message || 'Access denied or image not found' });
  }
};

export const shareBlog = async (req, res) => {
  try {
    const { userid } = req.headers;
    const { id } = req.params;
    const { toFriends = false, emails = [] } = req.body || {};
  // Prefer configured frontend base for public links; fallback to request origin
  const feBase = process.env.FRONTEND_BASE_URL;
  const proto = (req.headers['x-forwarded-proto'] || req.protocol || 'http').split(',')[0].trim();
  const host = (req.headers['x-forwarded-host'] || req.get('host'));
  const origin = (feBase && feBase.trim()) ? feBase.replace(/\/$/, '') : `${proto}://${host}`;

    // Compute slug from username + title (no spaces, remove unsafe chars)
    const { user, blog } = await blogService.assertOwner(userid, id);
    const titleNoSpaces = (blog.title || '').toString().replace(/\s+/g, '');
  const base = `${user.username || 'user'}${titleNoSpaces}`;
    const slug = base.replace(/[^a-zA-Z0-9_-]/g, '');
  // Pretty public URL under frontend: /blogs/:slug
  const url = `${origin}/blogs/${encodeURIComponent(slug)}`;

    const result = await blogService.shareBlog(userid, id, { toFriends, emails }, url);
    res.json(result);
  } catch (e) {
    res.status(e.status || 400).json({ error: e.message });
  }
};

export const resolveBlogSlug = async (req, res) => {
  try {
    const { slug } = req.params;
    const blogId = await blogService.resolveSlug(slug);
    if (!blogId) return res.status(404).json({ error: 'Not found' });
    // Redirect to SPA history route so the client router loads the blog
    const feBase = process.env.FRONTEND_BASE_URL;
    const proto = (req.headers['x-forwarded-proto'] || req.protocol || 'http').split(',')[0].trim();
    const host = (req.headers['x-forwarded-host'] || req.get('host'));
    const origin = (feBase && feBase.trim()) ? feBase.replace(/\/$/, '') : `${proto}://${host}`;
    return res.redirect(302, `${origin}/blogs/${blogId}/${encodeURIComponent(slug)}`);
  } catch (e) {
    res.status(400).json({ error: e.message });
  }
};

export const resolveBlogSlugId = async (req, res) => {
  try {
    const { slug } = req.params;
    const blogId = await blogService.resolveSlug(slug);
    if (!blogId) return res.status(404).json({ error: 'Not found' });
    res.json({ id: blogId });
  } catch (e) {
    res.status(400).json({ error: e.message });
  }
};
