import apiClient from "@/infrastructure/apiClient";
import apiPath from "@/infrastructure/apiPath";

// Error handling helper
const handleApiError = (error, context) => {
  if (error.response) {
    // Server responded with error status
    const { status, data } = error.response;
    console.error(`${context} failed:`, { status, data });

    switch (status) {
      case 400:
        throw new Error(data.message || "Dữ liệu không hợp lệ");
      case 401:
        throw new Error("Phiên đăng nhập đã hết hạn");
      case 403:
        throw new Error("Bạn không có quyền thực hiện hành động này");
      case 404:
        throw new Error("Không tìm thấy doanh thu");
      case 500:
        throw new Error("Lỗi máy chủ, vui lòng thử lại sau");
      default:
        throw new Error(data.message || "Có lỗi xảy ra");
    }
  } else if (error.request) {
    // Network error
    console.error(`${context} network error:`, error.request);
    throw new Error("Không thể kết nối đến máy chủ");
  } else {
    // Other error
    console.error(`${context} error:`, error.message);
    throw error;
  }
};

const incomeService = {
  /**
   * Tìm kiếm doanh thu với phân trang và bộ lọc
   * @param {Object} searchModel - Model tìm kiếm
   * @param {Object} searchModel.Pagination - Thông tin phân trang
   * @param {Object} searchModel.Search - Bộ lọc tìm kiếm
   * @param {Object} searchModel.Sort - Thông tin sắp xếp
   * @returns {Promise<Object>} Kết quả tìm kiếm
   */
  async search(searchModel) {
    try {
      const params = JSON.parse(JSON.stringify(searchModel));
      const response = await apiClient.post(apiPath.income.search, params);
      return response.data;
    } catch (error) {
      handleApiError(error, "Tìm kiếm doanh thu");
    }
  },

  /**
   * Lấy thông tin doanh thu theo ID
   * @param {string} id - ID của doanh thu (GUID)
   * @returns {Promise<Object|null>} Thông tin doanh thu
   */
  async getById(id) {
    try {
      const response = await apiClient.get(`${apiPath.income.getById}/${id}`);
      return response.data;
    } catch (error) {
      handleApiError(error, "Lấy thông tin doanh thu");
    }
  },

  /**
   * Tạo mới hoặc cập nhật doanh thu
   * @param {Object} incomeModel - Dữ liệu doanh thu
   * @returns {Promise<Object>} Kết quả tạo mới/cập nhật
   */
  async createOrUpdate(incomeModel) {
    try {
      const params = JSON.parse(JSON.stringify(incomeModel));
      const response = await apiClient.post(
        apiPath.income.createOrUpdate,
        params
      );
      return response.data;
    } catch (error) {
      handleApiError(error, "Tạo mới/cập nhật doanh thu");
    }
  },

  /**
   * Duyệt doanh thu
   * @param {string} id - ID của doanh thu
   * @returns {Promise<Object>} Kết quả duyệt
   */
  async approve(id) {
    try {
      const response = await apiClient.post(`${apiPath.income.approve}/${id}`);
      return response.data;
    } catch (error) {
      handleApiError(error, "Duyệt doanh thu");
    }
  },

  /**
   * Từ chối doanh thu
   * @param {string} id - ID của doanh thu
   * @param {string} rejectReason - Lý do từ chối
   * @returns {Promise<Object>} Kết quả từ chối
   */
  async reject(id, rejectReason) {
    try {
      const response = await apiClient.post(`${apiPath.income.reject}/${id}`, {
        RejectReason: rejectReason,
      });
      return response.data;
    } catch (error) {
      handleApiError(error, "Từ chối doanh thu");
    }
  },

  /**
   * Đánh dấu doanh thu đã nhận tiền
   * @param {string} id - ID của doanh thu
   * @param {string} note - Ghi chú về giao dịch
   * @returns {Promise<Object>} Kết quả đánh dấu
   */
  async markAsReceived(id, note) {
    try {
      const response = await apiClient.post(
        `${apiPath.income.markAsReceived}/${id}`,
        {
          Note: note,
        }
      );
      return response.data;
    } catch (error) {
      handleApiError(error, "Đánh dấu doanh thu đã nhận tiền");
    }
  },

  /**
   * Xóa doanh thu
   * @param {string} id - ID của doanh thu
   * @returns {Promise<Object>} Kết quả xóa
   */
  async delete(id) {
    try {
      const response = await apiClient.delete(`${apiPath.income.delete}/${id}`);
      return response.data;
    } catch (error) {
      handleApiError(error, "Xóa doanh thu");
    }
  },

  // Utility methods
  /**
   * Tạo model tìm kiếm mặc định
   * @returns {Object} Model tìm kiếm mặc định
   */
  createDefaultSearchModel() {
    return {
      Pagination: {
        PageIndex: 1,
        PageSize: 20,
      },
      Search: {
        PredicateObject: {
          Description: "",
          IncomeCategoryId: null,
          Status: null,
          CreatedStart: null,
          CreatedEnd: null,
        },
      },
      Sort: {
        Predicate: "CreatedDate",
        Reverse: true,
      },
      IsExport: false,
    };
  },

  /**
   * Tạo model doanh thu mặc định
   * @returns {Object} Model doanh thu mặc định
   */
  createDefaultIncomeModel() {
    return {
      Id: "00000000-0000-0000-0000-000000000000", // Guid.Empty for new income
      Description: "",
      Note: "",
      Amount: 0,
      IncomeCategoryId: null,
      Status: 0, // Pending
    };
  },

  /**
   * Lấy danh sách trạng thái doanh thu
   * @returns {Array} Danh sách trạng thái
   */
  getIncomeStatuses() {
    return [
      { value: 0, text: "Chờ duyệt", class: "warning" },
      { value: 1, text: "Đã duyệt", class: "success" },
      { value: 2, text: "Đã từ chối", class: "danger" },
      { value: 3, text: "Đã nhận tiền", class: "info" },
    ];
  },

  /**
   * Lấy tên trạng thái theo giá trị
   * @param {number} status - Giá trị trạng thái
   * @returns {string} Tên trạng thái
   */
  getStatusText(status) {
    const statuses = this.getIncomeStatuses();
    const found = statuses.find((s) => s.value === status);
    return found ? found.text : "Không xác định";
  },

  /**
   * Lấy class CSS cho trạng thái
   * @param {number} status - Giá trị trạng thái
   * @returns {string} Class CSS
   */
  getStatusClass(status) {
    const statuses = this.getIncomeStatuses();
    const found = statuses.find((s) => s.value === status);
    return found ? found.class : "secondary";
  },
};

export default incomeService;
