import { LoginUser } from '@tomei/sso';
import { ProductProductCollectionRepository } from './product-collection-product.repository';
import { ApplicationConfig } from '@tomei/config';
import { ProductBase } from '../../base';
import cuid = require('cuid');
import { ActionEnum, Activity } from '@tomei/activity-history';
import { SettingsCollectionModel } from '../../entities/settings-collection.entity';
import { ProductCollection } from '../collection-product/collection-product';
import { ObjectBase } from '@tomei/general';

export class ProductProductCollection extends ObjectBase {
  ObjectType = 'ProductProductCollection';
  ObjectId: string;
  ObjectName: string;
  TableName: string;
  ProductCollectionId: string;
  Code: string;
  ProductId: string;

  private static _Repo = new ProductProductCollectionRepository();

  public static async CheckProductAssignToCollection(
    code: string,
    dbTransaction?: any,
  ): Promise<any> {
    try {
      const options = {
        where: {
          Code: code,
        },
      };
      const productGroup = await this._Repo.findOne({
        ...options,
        transaction: dbTransaction,
      });
      if (productGroup) {
        return true;
      } else {
        return false;
      }
    } catch (error) {
      throw error;
    }
  }

  public static async listCollectionAssignedToProduct(
    ProductId: string,
    loginUser: LoginUser,
    dbTransaction?: any,
  ): Promise<any> {
    try {
      // Privilege checking
      const systemCode =
        ApplicationConfig.getComponentConfigValue('system-code');

      const isPrivileged = await loginUser.checkPrivileges(
        systemCode,
        'Product - List Collection',
      );
      if (!isPrivileged) {
        throw new Error(
          'You do not have permission to list product collection.',
        );
      }

      const options = {
        where: {
          ProductId: ProductId,
        },
        include: [
          {
            model: SettingsCollectionModel,
          },
        ],
      };
      const productCollection = await this._Repo
        .findAndCountAll(options)
        .then((collections) => {
          const productCollections = [];
          collections.rows.forEach((pg) => {
            productCollections.push(pg.ProductCollection);
          });
          return {
            count: collections.count,
            rows: productCollections,
          };
        });
      return productCollection;
    } catch (error) {
      throw error;
    }
  }

  public static async assignProductToCollection(
    Product: ProductBase,
    ProductCollection: ProductCollection,
    loginUser: LoginUser,
    dbTransaction?: any,
  ): Promise<any> {
    try {
      // Privilege checking
      const systemCode =
        ApplicationConfig.getComponentConfigValue('system-code');

      const isPrivileged = await loginUser.checkPrivileges(
        systemCode,
        'Product - Assign Collection',
      );
      if (!isPrivileged) {
        throw new Error(
          'You do not have permission to assign product Collection.',
        );
      }

      //Assign Product Collection
      const ProductCollectionId = cuid();
      ProductProductCollection._Repo.create({
        ProductCollectionId: ProductCollectionId,
        Code: ProductCollection.Code,
        ProductId: Product.ProductId,
      });

      const entityValueAfter = {
        ProductCollectionId: ProductCollectionId,
        Code: ProductCollection.Code,
        ProductId: Product.ProductId,
      };

      const activity = new Activity();
      activity.ActivityId = cuid();
      activity.Action = ActionEnum.CREATE;
      activity.Description = 'Assign Product to Product Collection';
      activity.EntityType = 'ProductProductCollection';
      activity.EntityId = ProductCollectionId;
      activity.EntityValueBefore = JSON.stringify({});
      activity.EntityValueAfter = JSON.stringify(entityValueAfter);
      await activity.create(loginUser.ObjectId, dbTransaction);
      return {
        MessageCode: 'ProductCollectionAssigned',
        Message: 'Product added to Product Collection.',
      };
    } catch (error) {
      throw error;
    }
  }

  public static async unassignedProductFromCollection(
    Product: ProductBase,
    ProductCollection: ProductCollection,
    loginUser: LoginUser,
    dbTransaction?: any,
  ): Promise<any> {
    try {
      // Privilege checking
      const systemCode =
        ApplicationConfig.getComponentConfigValue('system-code');

      const isPrivileged = await loginUser.checkPrivileges(
        systemCode,
        'Product - Unassigned Collection',
      );
      if (!isPrivileged) {
        throw new Error(
          'You do not have permission to unassigned product Collection.',
        );
      }

      //Unassigned Product Group
      const productCollection = await ProductProductCollection._Repo.findOne({
        where: { ProductId: Product.ProductId, Code: ProductCollection.Code },
        transaction: dbTransaction,
      });
      const ProductCollectionId = productCollection.ProductCollectionId;
      ProductProductCollection._Repo.delete(ProductCollectionId, dbTransaction);

      const EntityValueBefore = {
        ProductGroupId: productCollection.ProductCollectionId,
        Code: productCollection.Code,
        ProductId: productCollection.ProductId,
      };

      const activity = new Activity();
      activity.ActivityId = cuid();
      activity.Action = ActionEnum.DELETE;
      activity.Description = 'Unassigned Product from Product Collection';
      activity.EntityType = 'ProductProductCollection';
      activity.EntityId = ProductCollectionId;
      activity.EntityValueBefore = JSON.stringify(EntityValueBefore);
      activity.EntityValueAfter = JSON.stringify({});
      await activity.create(loginUser.ObjectId, dbTransaction);
      return {
        MessageCode: 'ProductCollectionUnassigned',
        Message: 'Product removed to Product Collection.',
      };
    } catch (error) {
      throw error;
    }
  }
}
