import { Injectable, Inject, NotFoundException, ForbiddenException } from '@nestjs/common';
import { STORE_REPOSITORY, IStoreRepository } from '../../domain/repositories/store.repository.interface';
import { EMPLOYEE_REPOSITORY, IEmployeeRepository } from '../../domain/repositories/employee.repository.interface';
import { Store } from '../../domain/entities/store.entity';
import { Employee } from '../../domain/entities/employee.entity';

@Injectable()
export class IssuerStoreService {
  constructor(
    @Inject(STORE_REPOSITORY)
    private readonly storeRepo: IStoreRepository,
    @Inject(EMPLOYEE_REPOSITORY)
    private readonly employeeRepo: IEmployeeRepository,
  ) {}

  // ---- Stores ----

  async listStores(
    issuerId: string,
    filters?: { level?: string; parentId?: string; status?: string },
  ): Promise<Store[]> {
    return this.storeRepo.findByIssuerId(issuerId, filters);
  }

  async createStore(issuerId: string, data: Partial<Store>): Promise<Store> {
    return this.storeRepo.create({
      ...data,
      issuerId,
      status: 'active',
    });
  }

  async updateStore(issuerId: string, storeId: string, data: Partial<Store>): Promise<Store> {
    const store = await this.storeRepo.findById(storeId);
    if (!store) throw new NotFoundException('Store not found');
    if (store.issuerId !== issuerId) throw new ForbiddenException('Store does not belong to this issuer');

    Object.assign(store, data);
    return this.storeRepo.save(store);
  }

  async deleteStore(issuerId: string, storeId: string): Promise<void> {
    const store = await this.storeRepo.findById(storeId);
    if (!store) throw new NotFoundException('Store not found');
    if (store.issuerId !== issuerId) throw new ForbiddenException('Store does not belong to this issuer');

    await this.storeRepo.delete(storeId);
  }

  // ---- Employees ----

  async listEmployees(
    issuerId: string,
    filters?: { storeId?: string; role?: string },
  ): Promise<Employee[]> {
    return this.employeeRepo.findByIssuerId(issuerId, filters);
  }

  async createEmployee(issuerId: string, data: Partial<Employee>): Promise<Employee> {
    return this.employeeRepo.create({
      ...data,
      issuerId,
      status: 'active',
    });
  }

  async updateEmployee(
    issuerId: string,
    employeeId: string,
    data: Partial<Employee>,
  ): Promise<Employee> {
    const employee = await this.employeeRepo.findById(employeeId);
    if (!employee) throw new NotFoundException('Employee not found');
    if (employee.issuerId !== issuerId) throw new ForbiddenException('Employee does not belong to this issuer');

    Object.assign(employee, data);
    return this.employeeRepo.save(employee);
  }

  async deleteEmployee(issuerId: string, employeeId: string): Promise<void> {
    const employee = await this.employeeRepo.findById(employeeId);
    if (!employee) throw new NotFoundException('Employee not found');
    if (employee.issuerId !== issuerId) throw new ForbiddenException('Employee does not belong to this issuer');

    await this.employeeRepo.delete(employeeId);
  }
}
