import { Response } from 'express';
import { AuthRequest } from '../../../middleware/auth';
import { authorService } from '../../../services/authorService';
import { logger } from "../../../config/logger";
import { prisma } from "../../../lib/prisma";
import { AuthorRole } from "@prisma/client";


export async function getAuthors(req: AuthRequest, res: Response): Promise<void> {
  try {
    const { role, page } = req.query;
    const response = await authorService.getAuthors(Number(page), role as string);
    res.json(response);
  } catch {
    res.status(500).json({ error: 'Server error' });
  }
}

export async function createAuthor(req: AuthRequest, res: Response): Promise<void> {
  try {
    if (!req.user?.permissions.isAdmin) {
      logger.warn(`Не администратор ${req.user?.id} пытается создать автора`);
      res.status(403).json({ error: 'Требуются права администратора' });
      return
    }

    const { email, displayName, bio, avatarUrl, okUrl, vkUrl, websiteUrl, roles } = req.body;

    // Проверим, что пришедшие роли валидны
    const validRoles = Array.isArray(roles)
        ? roles.filter((role: any): role is AuthorRole =>
            Object.values(AuthorRole).includes(role as AuthorRole)
        )
        : [];

    const lastAuthor = await prisma.author.findFirst({
      orderBy: {
        order: 'desc',
      },
    });

    const nextOrder = lastAuthor ? lastAuthor.order + 1 : 1;

    const author = await prisma.author.create({
      data: {
        email,
        displayName,
        bio,
        avatarUrl,
        order: nextOrder,
        okUrl,
        vkUrl,
        websiteUrl,
        roles: validRoles,
      },
      select: {
        id: true,
        email: true,
        displayName: true,
        bio: true,
        avatarUrl: true,
        order: true,
        okUrl: true,
        vkUrl: true,
        websiteUrl: true,
        roles: true,
      }
    });

    logger.info(`Успешное создание автора: ${author.id}`);
    res.status(201).json(author);
  } catch (error) {
    logger.error('Ошибка создания автора:', error);
    res.status(500).json({ error: 'Ошибка создания автора' });
  }
}

export async function updateAuthor(req: AuthRequest, res: Response): Promise<void> {
  try {
    if (!req.user?.permissions.isAdmin) {
      logger.warn(`Не администратор ${req.user?.id} пытается обновить автора`);
      res.status(403).json({ error: 'Требуются права администратора' });
      return
    }

    const { id } = req.params;
    const { email, displayName, bio, avatarUrl, order, okUrl, vkUrl, websiteUrl, roles } = req.body;

    // Проверим, что пришедшие роли валидны
    const validRoles = Array.isArray(roles)
        ? roles.filter((role: any): role is AuthorRole =>
            Object.values(AuthorRole).includes(role as AuthorRole)
        )
        : [];

    // Подготовка данных для изменения
    const updateData: any = {
      email,
      displayName,
      bio,
      avatarUrl,
      order,
      okUrl,
      vkUrl,
      websiteUrl,
      roles: validRoles,
    };

    // Обновление данных автора
    const author = await prisma.author.update({
      where: { id },
      data: updateData,
      select: {
        id: true,
        email: true,
        displayName: true,
        bio: true,
        avatarUrl: true,
        order: true,
        okUrl: true,
        vkUrl: true,
        websiteUrl: true,
        roles: true,
      }
    });

    logger.info(`Успешное обновление автора: ${author.id}`);
    res.json(author);
  } catch (error) {
    logger.error('Ошибка обновления автора:', error);
    res.status(500).json({ error: 'Ошибка обновления автора' });
  }
}

export async function deleteAuthor(req: AuthRequest, res: Response): Promise<void> {
  try {
    if (!req.user?.permissions.isAdmin) {
      logger.warn(`Не администратор ${req.user?.id} пытается удалить пользователя`);
      res.status(403).json({ error: 'Требуются права администратора' });
      return
    }

    const { id } = req.params;

    const existingUser = await prisma.author.findUnique({
      where: { id }
    });

    if (!existingUser) {
      res.status(404).json({ error: 'Автор не найден' });
      return
    }

    await prisma.author.delete({
      where: { id }
    });

    logger.info(`Успешное удаление автора: ${id}`);
    res.json({ message: 'Успешное удаление автора' });
  } catch (error) {
    logger.error('Ошибка удаления автора:', error);
    res.status(500).json({ error: 'Ошибка удаления автора' });
  }
}

export async function linkAuthorToUser(req: AuthRequest, res: Response): Promise<void> {
  try {
    if (!req.user?.permissions.isAdmin) {
      logger.warn(`Не администратор ${req.user?.id} пытается обновить автора`);
      res.status(403).json({ error: 'Требуются права администратора' });
      return
    }

    const { id } = req.params;
    const { userId } = req.body;

    const author = await prisma.author.update({
      where: { id },
      data: { userId },
      select: {
        id: true,
        userId: true,
      }
    });

    logger.info(`Успешное связывание автора: ${author.id} с пользователем ${author.userId}`);
    res.json(author);
  } catch (error) {
    logger.error('Ошибка связывания автора:', error);
    res.status(500).json({ error: 'Ошибка связывания автора' });
  }
}

export async function unlinkAuthorFromUser(req: AuthRequest, res: Response): Promise<void> {
  try {
    if (!req.user?.permissions.isAdmin) {
      logger.warn(`Не администратор ${req.user?.id} пытается обновить автора`);
      res.status(403).json({ error: 'Требуются права администратора' });
      return
    }

    const { id } = req.params;

    const author = await prisma.author.update({
      where: { id },
      data: { userId: null },
      select: {
        id: true,
        userId: true,
      }
    });

    logger.info(`Успешное отвязывание автора: ${author.id} от пользователя ${author.userId}`);
    res.json(author);
  } catch (error) {
    logger.error('Ошибка отвязывания автора:', error);
    res.status(500).json({ error: 'Ошибка отвязывания автора' });
  }
}

export async function toggleActiveAuthor(req: AuthRequest, res: Response) : Promise<void> {
  try {
    const { isActive } = req.body;

    if (!req.user) {
      res.status(401).json({ error: 'Пользователь не вошел в систему' });
      return
    }

    const author = await prisma.author.findUnique({
      where: { id: req.params.id }
    });

    if (!author) {
      res.status(404).json({ error: 'Автор не найден' });
      return
    }

    const updatedAuthor = await prisma.author.update({
      where: { id: req.params.id },
      data: { isActive: isActive },
    });

    res.json(updatedAuthor);
  } catch (error) {
    logger.error('Ошибка активирования автора:', error);
    res.status(500).json({ error: 'Серверная ошибка' });
  }
}

export async function reorderAuthor(req: AuthRequest, res: Response) : Promise<void> {
  try {
    if (!req.user) {
      res.status(401).json({ error: 'Пользователь не вошел в систему' });
      return
    }

    const { id } = req.params;
    const { direction } = req.body; // 'up' или 'down'

    if (!['up', 'down'].includes(direction)) {
      res.status(400).json({ error: 'Неправильное направление' });
      return
    }

    const current = await prisma.author.findUnique({ where: { id } });
    if (!current) {
      res.status(404).json({ error: 'Автор не найден' });
      return
    }
    const neighbor = await prisma.author.findFirst({
      where: {
        order: direction === 'up' ? { lt: current.order } : { gt: current.order },
      },
      orderBy: {
        order: direction === 'up' ? 'desc' : 'asc',
      },
    });

    if (!neighbor) {
      res.status(200).json({ message: 'Уже достигли границы', author: current });
      return
    }

    await prisma.$transaction([
      prisma.author.update({
        where: { id: current.id },
        data: { order: neighbor.order },
      }),
      prisma.author.update({
        where: { id: neighbor.id },
        data: { order: current.order },
      }),
    ]);

    const updated = await prisma.author.findUnique({ where: { id } });
    res.json(updated);
  } catch (error) {
    console.error('Ошибка при изменении порядка авторов:', error);
    res.status(500).json({ error: 'Ошибка при изменении порядка авторов' });  }
}
