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 chi phí');
      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 expenseService = {
  /**
   * Tìm kiếm chi phí 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.expense.search, params);
      return response.data;
    } catch (error) {
      handleApiError(error, 'Tìm kiếm chi phí');
    }
  },

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

  /**
   * Tạo mới chi phí
   * @param {Object} expenseData - Dữ liệu chi phí
   * @returns {Promise<Object>} Kết quả tạo mới
   */
  async create(expenseData) {
    try {
      const response = await apiClient.post(apiPath.expense.create, expenseData);
      return response.data;
    } catch (error) {
      handleApiError(error, 'Tạo mới chi phí');
    }
  },

  /**
   * Cập nhật chi phí
   * @param {string} id - ID của chi phí
   * @param {Object} expenseData - Dữ liệu chi phí
   * @returns {Promise<Object>} Kết quả cập nhật
   */
  async update(id, expenseData) {
    try {
      const response = await apiClient.put(`${apiPath.expense.update}/${id}`, expenseData);
      return response.data;
    } catch (error) {
      handleApiError(error, 'Cập nhật chi phí');
    }
  },

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

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

  /**
   * Từ chối chi phí
   * @param {string} id - ID của chi phí
   * @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.expense.reject}/${id}`, {
        RejectReason: rejectReason
      });
      return response.data;
    } catch (error) {
      handleApiError(error, 'Từ chối chi phí');
    }
  },

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

  /**
   * Bỏ duyệt chi phí (quay về trạng thái Chờ duyệt)
   * @param {string} id - ID của chi phí
   * @param {string} reason - Lý do bỏ duyệt
   * @returns {Promise<Object>} Kết quả bỏ duyệt
   */
  async unapprove(id, reason) {
    try {
      // TODO: Update endpoint when API is ready
      const response = await apiClient.post(`${apiPath.expense.unapprove}/${id}`, {
        Reason: reason
      });
      return response.data;
    } catch (error) {
      handleApiError(error, 'Bỏ duyệt chi phí');
    }
  },

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

  // 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,
        Total: 0
      },
      Search: {
        PredicateObject: {
          Keyword: "",
          ExpenseCategoryId: null,
          Status: null,
          CreatedStart: null,
          CreatedEnd: null
        }
      },
      Sort: {
        Predicate: "CreatedTime",
        Reverse: true
      },
      IsExport: false
    };
  },

  /**
   * Tạo model chi phí mặc định
   * @returns {Object} Model chi phí mặc định
   */
  createDefaultExpenseModel() {
    return {
      Id: "00000000-0000-0000-0000-000000000000", // Guid.Empty for new expense
      Description: "",
      Note: "",
      Amount: 0,
      ExpenseCategoryId: null,
      UserBankAccountId: null
    };
  },

  /**
   * Lấy danh sách trạng thái chi phí
   * @returns {Array} Danh sách trạng thái
   */
  getExpenseStatuses() {
    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: "Đã chuyể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.getExpenseStatuses();
    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.getExpenseStatuses();
    const found = statuses.find(s => s.value === status);
    return found ? found.class : "secondary";
  }
};

export default expenseService;
