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

import { NotFoundError, ConflictError } from '../../../errors/http-error';
import { getErrorMessage } from '../../../utils/error-utils';
import { CreateOrganizationDto, UpdateOrganizationDto } from '../identity.dto';

import { organizationService } from './organization.service';

/**
 * EN: Organization Controller
 * VI: Controller tổ chức
 */
export class OrganizationController {
  /**
   * EN: List organizations
   * VI: Liệt kê tổ chức
   */
  async list(req: Request, res: Response): Promise<void> {
    try {
      const skip = parseInt(req.query.skip as string) || 0;
      const take = parseInt(req.query.take as string) || 20;

      const result = await organizationService.list(skip, take);

      res.json({
        success: true,
        data: {
          organizations: result.organizations,
          pagination: {
            total: result.total,
            skip,
            take,
          },
        },
      });
    } catch (error: unknown) {
      res.status(500).json({
        success: false,
        error: {
          code: 'LIST_ORGANIZATIONS_FAILED',
          message: getErrorMessage(error) || 'Failed to list organizations',
        },
      });
    }
  }

  /**
   * EN: Create organization
   * VI: Tạo tổ chức
   */
  async create(req: Request, res: Response): Promise<void> {
    try {
      const data = CreateOrganizationDto.parse(req.body);
      const organization = await organizationService.create(data, req);

      res.status(201).json({
        success: true,
        data: organization,
        message: 'Organization created successfully / Tổ chức đã đượ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 ConflictError) {
        res.status(409).json(error.toApiResponse());
        return;
      }

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

  /**
   * EN: Get organization by ID
   * VI: Lấy tổ chức theo ID
   */
  async get(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      const organization = await organizationService.getById(id);

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

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

  /**
   * EN: Update organization
   * VI: Cập nhật tổ chức
   */
  async update(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      const data = UpdateOrganizationDto.parse(req.body);
      const organization = await organizationService.update(id, data, req);

      res.json({
        success: true,
        data: organization,
        message: 'Organization updated successfully / Tổ chức đã đượ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_ORGANIZATION_FAILED',
          message: getErrorMessage(error) || 'Failed to update organization',
        },
      });
    }
  }

  /**
   * EN: Delete organization
   * VI: Xóa tổ chức
   */
  async delete(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      await organizationService.delete(id, req);

      res.json({
        success: true,
        message: 'Organization deleted successfully / Tổ chức đã đượ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_ORGANIZATION_FAILED',
          message: getErrorMessage(error) || 'Failed to delete organization',
        },
      });
    }
  }

  /**
   * EN: Get organization users
   * VI: Lấy users của tổ chức
   */
  async getUsers(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      const skip = parseInt(req.query.skip as string) || 0;
      const take = parseInt(req.query.take as string) || 20;

      const result = await organizationService.getUsers(id, skip, take);

      res.json({
        success: true,
        data: {
          users: result.users,
          pagination: {
            total: result.total,
            skip,
            take,
          },
        },
      });
    } catch (error: unknown) {
      if (error instanceof NotFoundError) {
        res.status(404).json(error.toApiResponse());
        return;
      }

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

export const organizationController = new OrganizationController();
