
const db = require('../db/models');
const Claim_requestsDBApi = require('../db/api/claim_requests');
const ValidationError = require('./notifications/errors/validation');
const ForbiddenError = require('./notifications/errors/forbidden');

module.exports = class Claim_requestsService {
  static async create(data, currentUser) {
    const transaction = await db.sequelize.transaction();
    try {
      const business = await db.businesses.findByPk(data.businessId, { transaction });
      if (!business) throw new ValidationError('businessNotFound');
      if (business.owner_userId) throw new ValidationError('businessAlreadyOwned');

      const existingRequest = await db.claim_requests.findOne({
          where: {
              businessId: data.businessId,
              userId: currentUser.id,
              status: 'PENDING'
          },
          transaction
      });
      if (existingRequest) throw new ValidationError('claimRequestPending');

      const claim_request = await Claim_requestsDBApi.create(
        {
          businessId: data.businessId,
          userId: currentUser.id,
          status: 'PENDING',
        },
        { currentUser, transaction },
      );

      await transaction.commit();
      return claim_request;
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  }

  static async update(id, data, currentUser) {
    const transaction = await db.sequelize.transaction();
    try {
      const claim_request = await Claim_requestsDBApi.findBy({ id }, { transaction });
      if (!claim_request) throw new ValidationError('claimRequestNotFound');

      // Only admin can approve/reject
      if (currentUser.app_role?.name !== 'Administrator') {
          throw new ForbiddenError('forbidden');
      }

      const updatedRequest = await Claim_requestsDBApi.update(id, data, { currentUser, transaction });

      // If approved, update business ownership
      if (data.status === 'APPROVED') {
          await db.businesses.update(
              { owner_userId: claim_request.userId, is_claimed: true },
              { where: { id: claim_request.businessId }, transaction }
          );
          // Also link to user record
          await db.users.update(
              { businessId: claim_request.businessId },
              { where: { id: claim_request.userId }, transaction }
          );
      }

      await transaction.commit();
      return updatedRequest;
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  }

  static async findBy(id) {
      return await Claim_requestsDBApi.findBy({ id });
  }

  static async findAll(query, currentUser) {
      return await Claim_requestsDBApi.findAll(query, { currentUser });
  }
};
