import { Request, Response } from 'express';
import { z } from 'zod';

import { NotFoundError, ConflictError } from '../../../errors/http-error';
import { getErrorMessage } from '../../../utils/error-utils';
import { CreateGroupDto, UpdateGroupDto, AddGroupMemberDto } from '../identity.dto';

import { groupService } from './group.service';

/**
 * EN: Group Controller
 * VI: Controller nhóm
 */
export class GroupController {
  /**
   * EN: List groups by organization
   * VI: Liệt kê các nhóm theo tổ chức
   */
  async list(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params; // organizationId
      const groups = await groupService.getByOrganization(id);

      res.json({
        success: true,
        data: groups,
      });
    } catch (error: unknown) {
      res.status(500).json({
        success: false,
        error: {
          code: 'LIST_GROUPS_FAILED',
          message: getErrorMessage(error) || 'Failed to list groups',
        },
      });
    }
  }

  /**
   * EN: Create group
   * VI: Tạo nhóm
   */
  async create(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params; // organizationId
      const data = CreateGroupDto.parse(req.body);
      const group = await groupService.create(id, data, req);

      res.status(201).json({
        success: true,
        data: group,
        message: 'Group created successfully / Nhóm đã được tạo thành công',
      });
    } catch (error: unknown) {
      if (error instanceof z.ZodError) {
        res.status(400).json({
          success: false,
          error: {
            code: 'VALIDATION_ERROR',
            message: 'Invalid input',
            details: error.issues,
          },
        });
        return;
      }

      if (error instanceof NotFoundError || error instanceof ConflictError) {
        res.status(error.statusCode).json(error.toApiResponse());
        return;
      }

      res.status(500).json({
        success: false,
        error: {
          code: 'CREATE_GROUP_FAILED',
          message: getErrorMessage(error) || 'Failed to create group',
        },
      });
    }
  }

  /**
   * EN: Get group by ID
   * VI: Lấy nhóm theo ID
   */
  async get(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      const group = await groupService.getById(id);

      res.json({
        success: true,
        data: group,
      });
    } catch (error: unknown) {
      if (error instanceof NotFoundError) {
        res.status(404).json(error.toApiResponse());
        return;
      }

      res.status(500).json({
        success: false,
        error: {
          code: 'GET_GROUP_FAILED',
          message: getErrorMessage(error) || 'Failed to get group',
        },
      });
    }
  }

  /**
   * EN: Update group
   * VI: Cập nhật nhóm
   */
  async update(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      const data = UpdateGroupDto.parse(req.body);
      const group = await groupService.update(id, data, req);

      res.json({
        success: true,
        data: group,
        message: 'Group updated successfully / Nhóm đã được cập nhật thành công',
      });
    } catch (error: unknown) {
      if (error instanceof z.ZodError) {
        res.status(400).json({
          success: false,
          error: {
            code: 'VALIDATION_ERROR',
            message: 'Invalid input',
            details: error.issues,
          },
        });
        return;
      }

      if (error instanceof NotFoundError || error instanceof ConflictError) {
        res.status(error.statusCode).json(error.toApiResponse());
        return;
      }

      res.status(500).json({
        success: false,
        error: {
          code: 'UPDATE_GROUP_FAILED',
          message: getErrorMessage(error) || 'Failed to update group',
        },
      });
    }
  }

  /**
   * EN: Delete group
   * VI: Xóa nhóm
   */
  async delete(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      await groupService.delete(id, req);

      res.json({
        success: true,
        message: 'Group deleted successfully / Nhóm đã được xóa thành công',
      });
    } catch (error: unknown) {
      if (error instanceof NotFoundError || error instanceof ConflictError) {
        res.status(error.statusCode).json(error.toApiResponse());
        return;
      }

      res.status(500).json({
        success: false,
        error: {
          code: 'DELETE_GROUP_FAILED',
          message: getErrorMessage(error) || 'Failed to delete group',
        },
      });
    }
  }

  /**
   * EN: Get group members
   * VI: Lấy thành viên của nhóm
   */
  async getMembers(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      const members = await groupService.getMembers(id);

      res.json({
        success: true,
        data: members,
      });
    } catch (error: unknown) {
      res.status(500).json({
        success: false,
        error: {
          code: 'GET_GROUP_MEMBERS_FAILED',
          message: getErrorMessage(error) || 'Failed to get group members',
        },
      });
    }
  }

  /**
   * EN: Add member to group
   * VI: Thêm thành viên vào nhóm
   */
  async addMember(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      const data = AddGroupMemberDto.parse(req.body);
      const expiresAt = data.expiresAt ? new Date(data.expiresAt) : undefined;

      await groupService.addMember(id, data.userId, data.role, expiresAt, req);

      res.json({
        success: true,
        message: 'Member added successfully / Thành viên đã được thêm thành công',
      });
    } catch (error: unknown) {
      if (error instanceof z.ZodError) {
        res.status(400).json({
          success: false,
          error: {
            code: 'VALIDATION_ERROR',
            message: 'Invalid input',
            details: error.issues,
          },
        });
        return;
      }

      if (error instanceof NotFoundError) {
        res.status(404).json(error.toApiResponse());
        return;
      }

      res.status(500).json({
        success: false,
        error: {
          code: 'ADD_MEMBER_FAILED',
          message: getErrorMessage(error) || 'Failed to add member',
        },
      });
    }
  }

  /**
   * EN: Remove member from group
   * VI: Xóa thành viên khỏi nhóm
   */
  async removeMember(req: Request, res: Response): Promise<void> {
    try {
      const { id, userId } = req.params;
      await groupService.removeMember(id, userId, req);

      res.json({
        success: true,
        message: 'Member removed successfully / Thành viên đã được xóa thành công',
      });
    } catch (error: unknown) {
      if (error instanceof NotFoundError) {
        res.status(404).json(error.toApiResponse());
        return;
      }

      res.status(500).json({
        success: false,
        error: {
          code: 'REMOVE_MEMBER_FAILED',
          message: getErrorMessage(error) || 'Failed to remove member',
        },
      });
    }
  }
}

export const groupController = new GroupController();
