from django.db import models
from apps.utils.models import BaseModel, CommonBDModel, CommonBModel
from datetime import datetime
from django.db.models import Max, Sum


class WareHouse(CommonBModel):
    """
    TN:库房信息
    """
    number = models.CharField('库房编号', max_length=20)
    name = models.CharField('库房名称', max_length=20)
    place = models.CharField('具体地点', max_length=50)
    create_by = models.ForeignKey(
        'system.user', null=True, blank=True, on_delete=models.SET_NULL,
        verbose_name='创建人', related_name='mpr_warehouse_create_by')
    update_by = models.ForeignKey(
        'system.user', null=True, blank=True, on_delete=models.SET_NULL,
        verbose_name='最后编辑人', related_name='mpr_warehouse_update_by')
    belong_dept = models.ForeignKey(
        'system.dept', null=True, blank=True, on_delete=models.SET_NULL,
        verbose_name='所属部门', related_name='mpr_warehouse_belong_dept')


def _get_number(model_cls):
    today_str = datetime.now().strftime('%Y%m%d')
    prefix = model_cls.PREFIX
    last_record = model_cls.objects.filter(
        number__startswith=f"{prefix}-{today_str}"
    ).aggregate(Max('number'))['number__max']
    if last_record:
        last_number = int(last_record.split('-')[-1]) + 1
    else:
        last_number = 1
    return f"{prefix}-{today_str}-{last_number:04d}"


class PurchaseRequisition(CommonBDModel):
    """
    TN:物资申购单
    """
    PREFIX = 'WZSG'

    number = models.CharField('编号', max_length=20, unique=True)
    phone = models.CharField('联系电话', max_length=20, null=True, blank=True)
    req_date = models.DateField('申购日期', null=True, blank=True)
    total_amount = models.DecimalField('合计金额', max_digits=14, decimal_places=2, default=0)
    note = models.TextField('备注', null=True, blank=True)
    ticket = models.OneToOneField(
        'wf.ticket', verbose_name='关联工单',
        on_delete=models.SET_NULL, null=True, blank=True,
        related_name='mpr_ticket')

    @classmethod
    def get_a_number(cls):
        return _get_number(cls)


class PurchaseRequisitionItem(BaseModel):
    """
    TN:物资申购明细
    """
    requisition = models.ForeignKey(
        PurchaseRequisition, verbose_name='关联申购单',
        on_delete=models.CASCADE, related_name='items')
    item_name = models.CharField('物品名称', max_length=100)
    spec = models.CharField('规格及型号', max_length=200, null=True, blank=True)
    unit = models.CharField('单位', max_length=20, null=True, blank=True)
    req_quantity = models.DecimalField('申购数量', max_digits=12, decimal_places=3, default=0)
    current_stock = models.DecimalField('现库存量', max_digits=12, decimal_places=3, default=0)
    need_date = models.DateField('需用日期', null=True, blank=True)
    purchase_quantity = models.DecimalField('需采购数量', max_digits=12, decimal_places=3, default=0)
    unit_price = models.DecimalField('单价', max_digits=14, decimal_places=2, default=0)
    total_price = models.DecimalField('总价', max_digits=14, decimal_places=2, default=0)
    note = models.TextField('备注', null=True, blank=True)


class WarehouseEntry(CommonBDModel):
    """
    TN:仓库入库单
    """
    PREFIX = 'CKRK'

    ENTRY_TYPE_CHOICES = (
        ('raw_normal', '原材料正常入库'),
        ('raw_estimated', '原材料暂估入库'),
        ('product', '产品入库'),
        ('other', '其他'),
    )
    ENTRY_METHOD_CHOICES = (
        ('purchase', '采购'),
        ('self_made', '自制'),
        ('other', '其他'),
    )

    number = models.CharField('编号', max_length=20, unique=True)
    warehouse = models.ForeignKey(
        WareHouse, verbose_name='库房',
        on_delete=models.CASCADE, related_name='entries')
    entry_date = models.DateField('入库日期', null=True, blank=True)
    entry_type = models.CharField('入库类型', max_length=20, choices=ENTRY_TYPE_CHOICES, default='raw_normal')
    entry_method = models.CharField('入库方式', max_length=20, choices=ENTRY_METHOD_CHOICES, default='purchase')
    total_amount = models.DecimalField('合计金额', max_digits=14, decimal_places=2, default=0)
    note = models.TextField('备注', null=True, blank=True)
    ticket = models.OneToOneField(
        'wf.ticket', verbose_name='关联工单',
        on_delete=models.SET_NULL, null=True, blank=True,
        related_name='warehouse_entry_ticket')

    @classmethod
    def get_a_number(cls):
        return _get_number(cls)


class WarehouseEntryItem(BaseModel):
    """
    TN:入库明细
    """
    entry = models.ForeignKey(
        WarehouseEntry, verbose_name='关联入库单',
        on_delete=models.CASCADE, related_name='items')
    name = models.CharField('名称', max_length=100)
    spec = models.CharField('规格', max_length=200, null=True, blank=True)
    unit = models.CharField('单位', max_length=20, null=True, blank=True)
    quantity = models.DecimalField('数量', max_digits=12, decimal_places=3, default=0)
    unit_price = models.DecimalField('单价', max_digits=14, decimal_places=2, default=0)
    amount = models.DecimalField('金额', max_digits=14, decimal_places=2, default=0)
    supplier_name = models.CharField('供应商名称', max_length=100, null=True, blank=True)
    invoice_received = models.BooleanField('账单是否收到', default=False)
    note = models.TextField('备注', null=True, blank=True)


class WarehouseStock(BaseModel):
    """
    TN:物料库存（审批通过后入库）
    """
    STATUS_CHOICES = (
        ('idle', '闲置'),
        ('in_requisition', '领用中'),
        ('requisitioned', '已领用'),
    )

    warehouse = models.ForeignKey(
        WareHouse, verbose_name='库房',
        on_delete=models.CASCADE, related_name='mpr_stocks')
    entry = models.ForeignKey(
        WarehouseEntry, verbose_name='来源入库单',
        on_delete=models.SET_NULL, null=True, blank=True, related_name='stocks')
    entry_number = models.CharField('入库单号', max_length=20)
    entry_date = models.DateField('入库日期', null=True, blank=True)
    entry_type = models.CharField('入库类型', max_length=20, choices=WarehouseEntry.ENTRY_TYPE_CHOICES)
    entry_method = models.CharField('入库方式', max_length=20, choices=WarehouseEntry.ENTRY_METHOD_CHOICES)
    name = models.CharField('名称', max_length=100)
    spec = models.CharField('规格', max_length=200, null=True, blank=True)
    unit = models.CharField('单位', max_length=20, null=True, blank=True)
    quantity = models.DecimalField('数量', max_digits=12, decimal_places=3, default=0)
    unit_price = models.DecimalField('单价', max_digits=14, decimal_places=2, default=0)
    amount = models.DecimalField('金额', max_digits=14, decimal_places=2, default=0)
    supplier_name = models.CharField('供应商名称', max_length=100, null=True, blank=True)
    invoice_received = models.BooleanField('账单是否收到', default=False)
    status = models.CharField('状态', max_length=20, choices=STATUS_CHOICES, default='idle')


class MaterialRequisition(CommonBDModel):
    """
    TN:物资领用单
    """
    PREFIX = 'WZLY'

    number = models.CharField('编号', max_length=20, unique=True)
    req_date = models.DateField('填报时间', null=True, blank=True)
    collector = models.CharField('领取人', max_length=50, null=True, blank=True)
    note = models.TextField('备注', null=True, blank=True)
    ticket = models.OneToOneField(
        'wf.ticket', verbose_name='关联工单',
        on_delete=models.SET_NULL, null=True, blank=True,
        related_name='material_requisition_ticket')

    @classmethod
    def get_a_number(cls):
        return _get_number(cls)


class MaterialRequisitionItem(BaseModel):
    """
    TN:物资领用明细
    """
    requisition = models.ForeignKey(
        MaterialRequisition, verbose_name='关联领用单',
        on_delete=models.CASCADE, related_name='items')
    is_stock_item = models.BooleanField('是否库存物品', default=True)
    stock = models.ForeignKey(
        WarehouseStock, verbose_name='关联库存',
        on_delete=models.SET_NULL, null=True, blank=True, related_name='requisition_items')
    req_type = models.CharField('领用类型', max_length=50, null=True, blank=True)
    name = models.CharField('物资名称', max_length=100)
    spec = models.CharField('规格型号', max_length=200, null=True, blank=True)
    unit = models.CharField('单位', max_length=20, null=True, blank=True)
    quantity = models.DecimalField('领用量', max_digits=12, decimal_places=3, default=0)
    note = models.TextField('备注', null=True, blank=True)
