import 'package:superport_v2/features/inventory/transactions/domain/entities/stock_transaction.dart';

/// 입고 화면에서 사용하는 UI 전용 레코드 모델.
class InboundRecord {
  InboundRecord({
    this.id,
    required this.number,
    required this.transactionNumber,
    required this.transactionType,
    this.transactionTypeId,
    required this.processedAt,
    required this.warehouse,
    this.warehouseId,
    this.warehouseCode,
    this.warehouseZipcode,
    this.warehouseAddress,
    required this.status,
    this.statusId,
    required this.writer,
    this.writerId,
    required this.remark,
    required this.items,
    this.expectedReturnDate,
    this.isActive = true,
    this.partnerLinkId,
    this.partnerId,
    this.partnerCode,
    this.partnerName,
    this.raw,
  });

  factory InboundRecord.fromTransaction(StockTransaction transaction) {
    final partnerLink = transaction.customers.isNotEmpty
        ? transaction.customers.first
        : null;
    final partnerSummary = partnerLink?.customer;
    return InboundRecord(
      id: transaction.id,
      number: transaction.transactionNo,
      transactionNumber: transaction.transactionNo,
      transactionType: transaction.type.name,
      transactionTypeId: transaction.type.id,
      processedAt: transaction.transactionDate,
      warehouse: transaction.warehouse.name,
      warehouseId: transaction.warehouse.id,
      warehouseCode: transaction.warehouse.code,
      warehouseZipcode: transaction.warehouse.zipcode,
      warehouseAddress: transaction.warehouse.addressLine,
      status: transaction.status.name,
      statusId: transaction.status.id,
      writer: transaction.createdBy.name,
      writerId: transaction.createdBy.id,
      remark: transaction.note ?? '-',
      items: transaction.lines
          .map(InboundLineItem.fromLine)
          .toList(growable: false),
      expectedReturnDate: transaction.expectedReturnDate,
      isActive: transaction.isActive,
      partnerLinkId: partnerLink?.id,
      partnerId: partnerSummary?.id,
      partnerCode: partnerSummary?.code,
      partnerName: partnerSummary?.name,
      raw: transaction,
    );
  }

  final int? id;
  final String number;
  final String transactionNumber;
  final String transactionType;
  final int? transactionTypeId;
  final DateTime processedAt;
  final String warehouse;
  final int? warehouseId;
  final String? warehouseCode;
  final String? warehouseZipcode;
  final String? warehouseAddress;
  final String status;
  final int? statusId;
  final String writer;
  final int? writerId;
  final String remark;
  final List<InboundLineItem> items;
  final DateTime? expectedReturnDate;
  final bool isActive;
  final int? partnerLinkId;
  final int? partnerId;
  final String? partnerCode;
  final String? partnerName;
  final StockTransaction? raw;

  int get itemCount => items.length;

  int get totalQuantity =>
      items.fold<int>(0, (sum, item) => sum + item.quantity);

  double get totalAmount =>
      items.fold<double>(0, (sum, item) => sum + (item.price * item.quantity));

  /// 파트너사 정보가 존재하는지 여부를 반환한다.
  bool get hasPartner =>
      partnerId != null && (partnerName?.trim().isNotEmpty ?? false);

  /// 현재 레코드에 연결된 파트너사 고객 정보를 반환한다.
  StockTransactionCustomer? get primaryCustomer {
    final rawCustomers = raw?.customers;
    if (rawCustomers != null && rawCustomers.isNotEmpty) {
      return rawCustomers.first;
    }
    if (!hasPartner) {
      return null;
    }
    return StockTransactionCustomer(
      id: partnerLinkId,
      customer: StockTransactionCustomerSummary(
        id: partnerId!,
        code: partnerCode ?? '',
        name: partnerName ?? '',
      ),
    );
  }

  /// 현재 파트너사 고객 목록을 반환한다. `raw` 정보가 없을 경우 보조 필드를 활용한다.
  List<StockTransactionCustomer> get customers {
    final rawCustomers = raw?.customers;
    if (rawCustomers != null && rawCustomers.isNotEmpty) {
      return rawCustomers;
    }
    final fallback = primaryCustomer;
    if (fallback == null) {
      return const [];
    }
    return [fallback];
  }
}

/// 입고 상세 모달에서 사용하는 품목 정보.
class InboundLineItem {
  InboundLineItem({
    this.id,
    int? lineNo,
    int? productId,
    String? productCode,
    required this.product,
    required this.manufacturer,
    required this.unit,
    required this.quantity,
    required this.price,
    required this.remark,
  }) : lineNo = lineNo ?? 0,
       productId = productId ?? 0,
       productCode = productCode ?? '';

  factory InboundLineItem.fromLine(StockTransactionLine line) {
    final product = line.product;
    return InboundLineItem(
      id: line.id,
      lineNo: line.lineNo,
      productId: product.id,
      productCode: product.code,
      product: product.name,
      manufacturer: product.vendor?.name ?? '-',
      unit: product.uom?.name ?? '-',
      quantity: line.quantity,
      price: line.unitPrice,
      remark: line.note ?? '',
    );
  }

  final int? id;
  final int lineNo;
  final int productId;
  final String productCode;
  final String product;
  final String manufacturer;
  final String unit;
  final int quantity;
  final double price;
  final String remark;
}
