from __future__ import annotations

from rest_framework import serializers
from django.contrib.auth import get_user_model

from orgs.models import Organization, UserProfile
from .models import (
    MaterialCategory,
    Material,
    PriceList,
    PriceListItem,
    Customer,
    CustomerSite,
    ServiceAgreement,
    PickupOrder,
    PickupItem,
    WeighTicket,
    WeighLine,
    Invoice,
    InvoiceLine,
    Payment,
    Payout,
    ScrapListing,
    ScrapListingItem,
    ScrapBid,
    ScrapAward,
    ScrapListingInvite,
    Document,
    AuditLog,
)


User = get_user_model()


class OrganizationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Organization
        fields = ["id", "name", "code", "timezone", "currency_code", "created_at", "updated_at"]


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["id", "username", "email", "first_name", "last_name"]


class UserProfileSerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=True)

    class Meta:
        model = UserProfile
        fields = ["id", "user", "organization", "role", "created_at", "updated_at"]


class MaterialCategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = MaterialCategory
        fields = ["id", "organization", "name", "created_at", "updated_at"]


class MaterialSerializer(serializers.ModelSerializer):
    class Meta:
        model = Material
        fields = [
            "id",
            "organization",
            "category",
            "name",
            "code",
            "default_unit",
            "created_at",
            "updated_at",
        ]


class PriceListItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = PriceListItem
        fields = ["id", "price_list", "material", "unit", "unit_price", "direction", "created_at", "updated_at"]


class PriceListSerializer(serializers.ModelSerializer):
    items = PriceListItemSerializer(many=True, read_only=True)

    class Meta:
        model = PriceList
        fields = [
            "id",
            "organization",
            "name",
            "currency_code",
            "effective_from",
            "effective_to",
            "items",
            "created_at",
            "updated_at",
        ]


class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = [
            "id",
            "organization",
            "name",
            "email",
            "phone",
            "billing_address",
            "price_list",
            "created_at",
            "updated_at",
        ]


class CustomerSiteSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomerSite
        fields = [
            "id",
            "customer",
            "name",
            "address",
            "contact_name",
            "contact_phone",
            "contact_email",
            "created_at",
            "updated_at",
        ]


class ServiceAgreementSerializer(serializers.ModelSerializer):
    class Meta:
        model = ServiceAgreement
        fields = ["id", "customer", "site", "price_list", "valid_from", "valid_to", "created_at", "updated_at"]


class PickupItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = PickupItem
        fields = ["id", "pickup", "material", "estimated_qty", "unit", "created_at", "updated_at"]


class PickupOrderSerializer(serializers.ModelSerializer):
    items = PickupItemSerializer(many=True, read_only=True)

    class Meta:
        model = PickupOrder
        fields = [
            "id",
            "organization",
            "customer",
            "site",
            "status",
            "scheduled_at",
            "assigned_driver",
            "created_by",
            "completed_at",
            "notes",
            "items",
            "created_at",
            "updated_at",
        ]


class WeighLineSerializer(serializers.ModelSerializer):
    class Meta:
        model = WeighLine
        fields = ["id", "ticket", "material", "quantity", "unit", "created_at", "updated_at"]


class WeighTicketSerializer(serializers.ModelSerializer):
    lines = WeighLineSerializer(many=True, read_only=True)

    class Meta:
        model = WeighTicket
        fields = [
            "id",
            "pickup",
            "ticket_number",
            "gross_weight",
            "tare_weight",
            "net_weight",
            "unit",
            "recorded_by",
            "recorded_at",
            "lines",
            "created_at",
            "updated_at",
        ]


class InvoiceLineSerializer(serializers.ModelSerializer):
    class Meta:
        model = InvoiceLine
        fields = [
            "id",
            "invoice",
            "description",
            "material",
            "quantity",
            "unit",
            "unit_price",
            "line_total",
            "created_at",
            "updated_at",
        ]


class InvoiceSerializer(serializers.ModelSerializer):
    lines = InvoiceLineSerializer(many=True, read_only=True)

    class Meta:
        model = Invoice
        fields = [
            "id",
            "organization",
            "customer",
            "pickup",
            "currency_code",
            "total_amount",
            "status",
            "issued_at",
            "due_at",
            "lines",
            "created_at",
            "updated_at",
        ]


class PaymentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Payment
        fields = ["id", "invoice", "amount", "currency_code", "received_at", "reference", "created_at", "updated_at"]


class PayoutSerializer(serializers.ModelSerializer):
    class Meta:
        model = Payout
        fields = ["id", "organization", "customer", "pickup", "amount", "currency_code", "paid_at", "reference", "created_at", "updated_at"]


class ScrapListingItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = ScrapListingItem
        fields = ["id", "listing", "material", "quantity_estimate", "unit", "created_at", "updated_at"]


class ScrapListingSerializer(serializers.ModelSerializer):
    items = ScrapListingItemSerializer(many=True, read_only=True)

    class Meta:
        model = ScrapListing
        fields = [
            "id",
            "organization",
            "customer",
            "site",
            "title",
            "description",
            "auction_type",
            "currency_code",
            "reserve_price",
            "min_increment",
            "starts_at",
            "ends_at",
            "status",
            "is_public",
            "created_by",
            "items",
            "created_at",
            "updated_at",
        ]


class ScrapBidSerializer(serializers.ModelSerializer):
    class Meta:
        model = ScrapBid
        fields = [
            "id",
            "listing",
            "bidder_org",
            "bidder_user",
            "price_total",
            "message",
            "status",
            "created_at",
            "updated_at",
        ]


class ScrapAwardSerializer(serializers.ModelSerializer):
    class Meta:
        model = ScrapAward
        fields = ["id", "listing", "winning_bid", "pickup", "notes", "created_at", "updated_at"]


class ScrapListingInviteSerializer(serializers.ModelSerializer):
    class Meta:
        model = ScrapListingInvite
        fields = ["id", "listing", "invited_org", "invited_user", "created_at", "updated_at"]


class DocumentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Document
        fields = [
            "id",
            "organization",
            "file",
            "kind",
            "content_type",
            "object_id",
            "uploaded_by",
            "created_at",
            "updated_at",
        ]


class AuditLogSerializer(serializers.ModelSerializer):
    class Meta:
        model = AuditLog
        fields = [
            "id",
            "organization",
            "user",
            "action",
            "content_type",
            "object_id",
            "metadata",
            "created_at",
            "updated_at",
        ]
