import { DataSource } from 'typeorm';
import { User } from '../../../repositories/users/entity/user.entity';
import { Account } from '../../../repositories/accounts/entity/account.entity';
import {
  License,
  CardLicense,
  CardLicenseIssue,
  LicenseAllocationHistory,
} from '../../../repositories/licenses/entity/license.entity';

export const createAccount = async (
  datasource: DataSource,
): Promise<{ accountId: number }> => {
  const { identifiers } = await datasource.getRepository(Account).insert({
    tier: 1,
    country: 'JP',
    delegation_permission: false,
    locked: false,
    company_name: 'test inc.',
    verified: true,
    deleted_at: '',
    created_by: 'test_runner',
    created_at: new Date(),
    updated_by: 'updater',
    updated_at: new Date(),
  });
  const account = identifiers.pop() as Account;
  return { accountId: account.id };
};

export const createUser = async (
  datasource: DataSource,
  accountId: number,
  external_id: string,
  role: string,
  author_id?: string | undefined,
): Promise<{ userId: number; externalId: string }> => {
  const { identifiers } = await datasource.getRepository(User).insert({
    account_id: accountId,
    external_id: external_id,
    role: role,
    accepted_terms_version: '1.0',
    author_id: author_id,
    email_verified: true,
    auto_renew: true,
    license_alert: true,
    notification: true,
    encryption: false,
    prompt: false,
    created_by: 'test_runner',
    created_at: new Date(),
    updated_by: 'updater',
    updated_at: new Date(),
  });
  const user = identifiers.pop() as User;
  return { userId: user.id, externalId: external_id };
};

export const createLicense = async (
  datasource: DataSource,
  licenseId: number,
  expiry_date: Date,
  accountId: number,
  type: string,
  status: string,
  allocated_user_id: number,
): Promise<void> => {
  const { identifiers } = await datasource.getRepository(License).insert({
    id: licenseId,
    expiry_date: expiry_date,
    account_id: accountId,
    type: type,
    status: status,
    allocated_user_id: allocated_user_id,
    order_id: null,
    deleted_at: null,
    delete_order_id: null,
    created_by: 'test_runner',
    created_at: new Date(),
    updated_by: 'updater',
    updated_at: new Date(),
  });
  identifiers.pop() as License;
};

export const createCardLicense = async (
  datasource: DataSource,
  licenseId: number,
  issueId: number,
  cardLicenseKey: string,
): Promise<void> => {
  const { identifiers } = await datasource.getRepository(CardLicense).insert({
    license_id: licenseId,
    issue_id: issueId,
    card_license_key: cardLicenseKey,
    activated_at: null,
    created_by: 'test_runner',
    created_at: new Date(),
    updated_by: 'updater',
    updated_at: new Date(),
  });
  identifiers.pop() as CardLicense;
};

export const createCardLicenseIssue = async (
  datasource: DataSource,
  issueId: number,
): Promise<void> => {
  const { identifiers } = await datasource
    .getRepository(CardLicenseIssue)
    .insert({
      id: issueId,
      issued_at: new Date(),
      created_by: 'test_runner',
      created_at: new Date(),
      updated_by: 'updater',
      updated_at: new Date(),
    });
  identifiers.pop() as CardLicenseIssue;
};

export const createLicenseAllocationHistory = async (
  datasource: DataSource,
  historyId: number,
  userId: number,
  licenseId: number,
  type: string,
): Promise<void> => {
  const { identifiers } = await datasource
    .getRepository(LicenseAllocationHistory)
    .insert({
      id: historyId,
      user_id: userId,
      license_id: licenseId,
      is_allocated: true,
      executed_at: new Date(),
      switch_from_type: type,
      deleted_at: null,
      created_by: null,
      created_at: new Date(),
      updated_by: null,
      updated_at: new Date(),
    });
  identifiers.pop() as LicenseAllocationHistory;
};

export const selectCardLicensesCount = async (
  datasource: DataSource,
): Promise<{ count: number }> => {
  const count = await datasource.getRepository(CardLicense).count();
  return { count: count };
};

export const selectCardLicense = async (
  datasource: DataSource,
  cardLicenseKey: string,
): Promise<{ cardLicense: CardLicense }> => {
  const cardLicense = await datasource.getRepository(CardLicense).findOne({
    where: {
      card_license_key: cardLicenseKey,
    },
  });
  return { cardLicense };
};

export const selectLicense = async (
  datasource: DataSource,
  id: number,
): Promise<{ license: License }> => {
  const license = await datasource.getRepository(License).findOne({
    where: {
      id: id,
    },
  });
  return { license };
};

export const selectLicenseAllocationHistory = async (
  datasource: DataSource,
  userId: number,
  licence_id: number,
): Promise<{ licenseAllocationHistory: LicenseAllocationHistory }> => {
  const licenseAllocationHistory = await datasource
    .getRepository(LicenseAllocationHistory)
    .findOne({
      where: {
        user_id: userId,
        license_id: licence_id,
      },
      order: {
        executed_at: 'DESC',
      },
    });
  return { licenseAllocationHistory };
};
