# api/serializers.py
from rest_framework import serializers
from django.contrib.auth import get_user_model
from inventory.models import Product, ProductCategory, InventoryTransaction, Supplier, PurchaseOrder
from sales.models import POSOrder, POSOrderItem, Customer
from accounts.models import AuditLog
from core.models import Branch, SystemSettings

User = get_user_model()


# ── Auth ──────────────────────────────────────────────────────────────────────

class LoginSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField(write_only=True)


class UserSerializer(serializers.ModelSerializer):
    role_display = serializers.CharField(source='get_role_display', read_only=True)
    branch_name  = serializers.CharField(source='branch.name', read_only=True, default=None)

    class Meta:
        model  = User
        fields = ['id', 'username', 'first_name', 'last_name', 'email',
                  'role', 'role_display', 'branch', 'branch_name',
                  'is_active', 'date_joined']
        read_only_fields = ['id', 'date_joined']


class UserCreateSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)
    pin_raw  = serializers.CharField(write_only=True, required=False, allow_blank=True)

    class Meta:
        model  = User
        fields = ['username', 'first_name', 'last_name', 'email',
                  'password', 'role', 'branch', 'pin_raw']

    def create(self, validated_data):
        pin_raw = validated_data.pop('pin_raw', None)
        password = validated_data.pop('password')
        user = User(**validated_data)
        user.set_password(password)
        if pin_raw:
            user.set_pin(pin_raw)
        user.save()
        return user


# ── Branch ────────────────────────────────────────────────────────────────────

class BranchSerializer(serializers.ModelSerializer):
    class Meta:
        model  = Branch
        fields = ['id', 'name', 'code', 'address', 'phone', 'is_active', 'created_at']
        read_only_fields = ['id', 'created_at']


# ── Inventory ─────────────────────────────────────────────────────────────────

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model  = ProductCategory
        fields = ['id', 'name', 'description', 'created_at']
        read_only_fields = ['id', 'created_at']


class ProductSerializer(serializers.ModelSerializer):
    category_name = serializers.CharField(source='category.name', read_only=True)
    stock_status  = serializers.CharField(read_only=True)
    selling_price = serializers.DecimalField(source='price', max_digits=10, decimal_places=2, read_only=True)
    current_stock = serializers.IntegerField(source='stock_quantity', read_only=True)
    low_stock_threshold = serializers.IntegerField(source='minimum_stock', read_only=True)
    is_active = serializers.SerializerMethodField()

    class Meta:
        model  = Product
        fields = ['id', 'name', 'sku', 'barcode', 'description',
                  'category', 'category_name',
                  'selling_price', 'cost_price',
                  'current_stock', 'low_stock_threshold',
                  'stock_status', 'is_active',
                  'created_at']
        read_only_fields = ['id', 'stock_status', 'created_at']

    def get_is_active(self, obj):
        return obj.status == 'active'


class StockAdjustSerializer(serializers.Serializer):
    action      = serializers.ChoiceField(choices=['restock', 'reduce', 'adjust'])
    quantity    = serializers.IntegerField(min_value=0)
    note        = serializers.CharField(required=False, allow_blank=True)
    new_stock   = serializers.IntegerField(required=False, min_value=0)  # for adjust


class InventoryTransactionSerializer(serializers.ModelSerializer):
    product_name = serializers.CharField(source='product.name', read_only=True)

    class Meta:
        model  = InventoryTransaction
        fields = ['id', 'product', 'product_name', 'transaction_type',
                  'quantity', 'notes', 'created_at']
        read_only_fields = ['id', 'created_at']


class SupplierSerializer(serializers.ModelSerializer):
    class Meta:
        model  = Supplier
        fields = ['id', 'name', 'email', 'phone', 'address',
                  'total_purchases', 'outstanding_balance', 'created_at']
        read_only_fields = ['id', 'total_purchases', 'outstanding_balance', 'created_at']


class PurchaseOrderSerializer(serializers.ModelSerializer):
    supplier_name = serializers.CharField(source='supplier.name', read_only=True)

    class Meta:
        model  = PurchaseOrder
        fields = ['id', 'supplier', 'supplier_name', 'status',
                  'total_amount', 'notes', 'created_at', 'received_at']
        read_only_fields = ['id', 'created_at', 'received_at']


# ── Sales ─────────────────────────────────────────────────────────────────────

class OrderItemSerializer(serializers.ModelSerializer):
    product_name = serializers.CharField(source='product.name', read_only=True)

    class Meta:
        model  = POSOrderItem
        fields = ['id', 'product', 'product_name', 'quantity',
                  'unit_price', 'discount', 'total_price']
        read_only_fields = ['id', 'total_price']


class OrderItemCreateSerializer(serializers.Serializer):
    product_id = serializers.IntegerField()
    quantity   = serializers.IntegerField(min_value=1)
    discount   = serializers.DecimalField(max_digits=5, decimal_places=2, default=0)


class OrderSerializer(serializers.ModelSerializer):
    items        = OrderItemSerializer(many=True, read_only=True, source='posorderitem_set')
    cashier_name = serializers.CharField(source='cashier.username', read_only=True)

    class Meta:
        model  = POSOrder
        fields = ['id', 'order_number', 'cashier', 'cashier_name',
                  'customer_name', 'customer_phone',
                  'payment_method', 'amount_paid', 'final_amount',
                  'payment_status', 'balance_amount', 'status', 'branch',
                  'items', 'created_at']
        read_only_fields = ['id', 'order_number', 'payment_status', 'balance_amount', 'status', 'created_at']


class OrderCreateSerializer(serializers.Serializer):
    customer_name  = serializers.CharField(required=False, allow_blank=True)
    customer_phone = serializers.CharField(required=False, allow_blank=True)
    payment_method = serializers.ChoiceField(
        choices=['cash', 'transfer', 'pos', 'mobile_money', 'credit'],
        default='cash'
    )
    amount_paid    = serializers.DecimalField(max_digits=10, decimal_places=2, default=0)
    discount       = serializers.DecimalField(max_digits=5, decimal_places=2, default=0)
    branch         = serializers.IntegerField(required=False)
    items          = OrderItemCreateSerializer(many=True)


# ── Customer ──────────────────────────────────────────────────────────────────

class CustomerSerializer(serializers.ModelSerializer):
    total_orders      = serializers.IntegerField(read_only=True)
    total_spent       = serializers.DecimalField(max_digits=15, decimal_places=2, read_only=True)
    outstanding_balance = serializers.DecimalField(max_digits=15, decimal_places=2, read_only=True)

    class Meta:
        model  = Customer
        fields = ['id', 'name', 'phone', 'email', 'address', 'notes',
                  'total_orders', 'total_spent', 'outstanding_balance', 'created_at']
        read_only_fields = ['id', 'created_at']


# ── Audit Log ─────────────────────────────────────────────────────────────────

class AuditLogSerializer(serializers.ModelSerializer):
    user_name = serializers.CharField(source='user.username', read_only=True)

    class Meta:
        model  = AuditLog
        fields = ['id', 'user', 'user_name', 'action', 'target',
                  'ip_address', 'timestamp']
        read_only_fields = ['id', 'timestamp']


# ── Dashboard / P&L ───────────────────────────────────────────────────────────

class DashboardSerializer(serializers.Serializer):
    today_sales        = serializers.DecimalField(max_digits=15, decimal_places=2)
    today_transactions = serializers.IntegerField()
    today_customers    = serializers.IntegerField()
    avg_order_value    = serializers.DecimalField(max_digits=15, decimal_places=2)
    low_stock_products = serializers.IntegerField()
    total_users        = serializers.IntegerField()


class PnLSerializer(serializers.Serializer):
    date_from          = serializers.DateField()
    date_to            = serializers.DateField()
    total_revenue      = serializers.DecimalField(max_digits=15, decimal_places=2)
    total_cost         = serializers.DecimalField(max_digits=15, decimal_places=2)
    total_profit       = serializers.DecimalField(max_digits=15, decimal_places=2)
    credit_outstanding = serializers.DecimalField(max_digits=15, decimal_places=2)
    total_orders_count = serializers.IntegerField()
