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

import { NotFoundError, BadRequestError } from '../../../errors/http-error';
import { getErrorMessage } from '../../../utils/error-utils';
import { CreateAccessReviewDto, ReviewAccessItemDto } from '../access.dto';

import { accessReviewService } from './review.service';

/**
 * EN: Access Review Controller
 * VI: Controller đánh giá truy cập
 */
export class AccessReviewController {
  /**
   * EN: List reviews
   * VI: Liệt kê các đánh giá
   */
  async list(req: Request, res: Response): Promise<void> {
    try {
      const status = req.query.status as string | undefined;
      const reviews = await accessReviewService.list(status as any);

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

  /**
   * EN: Create review
   * VI: Tạo đánh giá
   */
  async create(req: Request, res: Response): Promise<void> {
    try {
      const createdBy = (req as any).user?.id;
      if (!createdBy) {
        res.status(401).json({
          success: false,
          error: {
            code: 'UNAUTHORIZED',
            message: 'Authentication required / Yêu cầu xác thực',
          },
        });
        return;
      }

      const data = CreateAccessReviewDto.parse(req.body);
      const review = await accessReviewService.createReview(data, createdBy, req);

      res.status(201).json({
        success: true,
        data: review,
        message: 'Access review created successfully / Đánh giá truy cập đã đượ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 BadRequestError) {
        res.status(400).json(error.toApiResponse());
        return;
      }

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

  /**
   * EN: Get review
   * VI: Lấy đánh giá
   */
  async get(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      const review = await accessReviewService.getReview(id);

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

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

  /**
   * EN: Start review
   * VI: Bắt đầu đánh giá
   */
  async start(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      const review = await accessReviewService.startReview(id, req);

      res.json({
        success: true,
        data: review,
        message: 'Access review started successfully / Đánh giá truy cập đã được bắt đầu thành công',
      });
    } catch (error: unknown) {
      if (error instanceof NotFoundError || error instanceof BadRequestError) {
        res.status(error.statusCode).json(error.toApiResponse());
        return;
      }

      res.status(500).json({
        success: false,
        error: {
          code: 'START_REVIEW_FAILED',
          message: getErrorMessage(error) || 'Failed to start review',
        },
      });
    }
  }

  /**
   * EN: Complete review
   * VI: Hoàn thành đánh giá
   */
  async complete(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      const review = await accessReviewService.completeReview(id, req);

      res.json({
        success: true,
        data: review,
        message: 'Access review completed successfully / Đánh giá truy cập đã được hoàn thành thành công',
      });
    } catch (error: unknown) {
      if (error instanceof NotFoundError || error instanceof BadRequestError) {
        res.status(error.statusCode).json(error.toApiResponse());
        return;
      }

      res.status(500).json({
        success: false,
        error: {
          code: 'COMPLETE_REVIEW_FAILED',
          message: getErrorMessage(error) || 'Failed to complete review',
        },
      });
    }
  }

  /**
   * EN: Get review items
   * VI: Lấy các items đánh giá
   */
  async getItems(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params;
      const items = await accessReviewService.getReviewItems(id);

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

  /**
   * EN: Review item
   * VI: Đánh giá item
   */
  async reviewItem(req: Request, res: Response): Promise<void> {
    try {
      const { itemId } = req.params;
      const reviewerId = (req as any).user?.id;
      if (!reviewerId) {
        res.status(401).json({
          success: false,
          error: {
            code: 'UNAUTHORIZED',
            message: 'Authentication required / Yêu cầu xác thực',
          },
        });
        return;
      }

      const data = ReviewAccessItemDto.parse(req.body);
      const item = await accessReviewService.reviewItem(itemId, reviewerId, data.status, data.comments, req);

      res.json({
        success: true,
        data: item,
        message: 'Review item updated successfully / Item đánh giá đã đượ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 BadRequestError) {
        res.status(error.statusCode).json(error.toApiResponse());
        return;
      }

      res.status(500).json({
        success: false,
        error: {
          code: 'REVIEW_ITEM_FAILED',
          message: getErrorMessage(error) || 'Failed to review item',
        },
      });
    }
  }
}

export const accessReviewController = new AccessReviewController();
