import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Order } from '../entities/order.entity';
import { OrderItem } from '../entities/order-item.entity';
import { CreateOrderDto } from '../dto/create-order.dto';
import { UpdateOrderDto } from '../dto/update-order.dto';
import { ProductionLineService } from './production-line.service';

@Injectable()
export class OrderService {
  constructor(
    @InjectRepository(Order)
    private orderRepository: Repository<Order>,
    @InjectRepository(OrderItem)
    private orderItemRepository: Repository<OrderItem>,
    private productionLineService: ProductionLineService,
  ) {}

  async create(createDto: CreateOrderDto): Promise<Order> {
    const order = this.orderRepository.create({
      ...createDto,
      orderNumber: `ORD-${Date.now()}`,
      status: 'pending' as const,
      paymentStatus: 'pending' as const,
    });

    const savedOrder = await this.orderRepository.save(order);

    // Create order items
    const items = createDto.items.map(item => ({
      ...item,
      orderId: savedOrder.id,
    }));

    await this.orderItemRepository.save(items);

    // Assign to production line
    for (const item of items) {
      const availableLines = await this.productionLineService.getAvailableLines(item.type);
      if (availableLines.length > 0) {
        // Note: item.id doesn't exist yet, would need to save items first
        // await this.assignToProductionLine(savedOrder.id, item.id, availableLines[0].id);
      }
    }

    return savedOrder;
  }

  async findAll(): Promise<Order[]> {
    return this.orderRepository.find({
      relations: ['customer', 'items', 'items.productionLine'],
      order: {
        createdAt: 'DESC',
      },
    });
  }

  async findOne(id: string): Promise<Order> {
    return this.orderRepository.findOne({
      where: { id },
      relations: ['customer', 'items', 'items.productionLine'],
    });
  }

  async update(id: string, updateDto: UpdateOrderDto): Promise<Order> {
    await this.orderRepository.update(id, updateDto);
    return this.findOne(id);
  }

  async remove(id: string): Promise<void> {
    await this.orderRepository.delete(id);
  }

  async updateOrderStatus(orderId: string, status: 'pending' | 'processing' | 'completed' | 'cancelled'): Promise<Order> {
    await this.orderRepository.update(orderId, { status });
    return this.findOne(orderId);
  }

  async updatePaymentStatus(orderId: string, status: 'pending' | 'paid' | 'failed'): Promise<Order> {
    await this.orderRepository.update(orderId, { paymentStatus: status });
    return this.findOne(orderId);
  }

  async assignToProductionLine(
    orderId: string,
    itemId: string,
    productionLineId: string,
  ): Promise<void> {
    await this.orderItemRepository.update(itemId, {
      productionLineId,
      status: 'in_progress' as const,
    });
  }

  async getOrdersByStatus(status: 'pending' | 'processing' | 'completed' | 'cancelled'): Promise<Order[]> {
    return this.orderRepository.find({
      where: { status },
      relations: ['customer', 'items', 'items.productionLine'],
    });
  }

  async getOrdersByCustomer(customerId: string): Promise<Order[]> {
    return this.orderRepository.find({
      where: { customerId },
      relations: ['customer', 'items', 'items.productionLine'],
    });
  }

  // Additional methods for controller compatibility
  async updateStatus(id: string, status: string): Promise<Order> {
    return this.updateOrderStatus(id, status as any);
  }

  async findByStatus(status: string): Promise<Order[]> {
    return this.getOrdersByStatus(status as any);
  }

  async findByCustomer(customerId: string): Promise<Order[]> {
    return this.getOrdersByCustomer(customerId);
  }

  async findByPriority(priority: string): Promise<Order[]> {
    // This would need priority field in Order entity
    return this.findAll();
  }
}
