from rest_framework import serializers

from apps.investments.models import Investment, InvestmentAllocation, InvestmentCertificate
from apps.investors.models import Beneficiary, Investor
from apps.projects.models import Project, ProjectInvestmentTerms
from apps.transactions.models import Transaction
from apps.documents.models import Document
from apps.statements.models import Statement
from apps.notifications.models import Notification, NotificationPreference
from apps.transparency.models import TransparencyEvent
from apps.reports.models import Report
from apps.support.models import SupportTicket, TicketMessage
from apps.audit.models import AuditLog
from apps.cms.models import (
    BlogPost,
    CompanyProfileSection,
    ContactInquiry,
    GalleryItem,
    LeadershipProfile,
    ShowcaseVideo,
    TeamMember,
)


class AllocationSerializer(serializers.ModelSerializer):
    class Meta:
        model = InvestmentAllocation
        fields = ("id", "label", "percent", "amount")


class InvestmentSerializer(serializers.ModelSerializer):
    project_name = serializers.CharField(source="project.name", read_only=True)
    project_slug = serializers.CharField(source="project.slug", read_only=True)
    project_progress = serializers.DecimalField(
        source="project.progress_percent", max_digits=5, decimal_places=2, read_only=True
    )
    allocations = AllocationSerializer(many=True, read_only=True)
    investor_code = serializers.CharField(source="investor.account_code", read_only=True)
    investor_email = serializers.EmailField(source="investor.user.email", read_only=True)
    investor = serializers.PrimaryKeyRelatedField(queryset=Investor.objects.all())
    project = serializers.PrimaryKeyRelatedField(queryset=Project.objects.all())

    class Meta:
        model = Investment
        fields = (
            "id",
            "investor",
            "investor_code",
            "investor_email",
            "project",
            "agreement_code",
            "status",
            "currency",
            "committed_amount",
            "received_amount",
            "expected_benefit",
            "benefit_received",
            "participation_percent",
            "profit_share_percent",
            "reference",
            "source",
            "payment_method",
            "payment_reference",
            "payment_verified_at",
            "agreement_accepted_at",
            "activated_at",
            "next_distribution_on",
            "agreement_executed_on",
            "project_name",
            "project_slug",
            "project_progress",
            "allocations",
            "created_at",
        )
        read_only_fields = (
            "id",
            "reference",
            "participation_percent",
            "profit_share_percent",
            "payment_verified_at",
            "activated_at",
            "created_at",
        )


class TransactionSerializer(serializers.ModelSerializer):
    project_name = serializers.CharField(source="project.name", read_only=True)
    investor_code = serializers.CharField(source="investor.account_code", read_only=True)
    investor_email = serializers.EmailField(source="investor.user.email", read_only=True)
    investor = serializers.PrimaryKeyRelatedField(queryset=Investor.objects.all())
    investment = serializers.PrimaryKeyRelatedField(queryset=Investment.objects.all(), required=False, allow_null=True)
    project = serializers.PrimaryKeyRelatedField(queryset=Project.objects.all(), required=False, allow_null=True)

    class Meta:
        model = Transaction
        fields = (
            "id",
            "reference",
            "investor",
            "investor_code",
            "investor_email",
            "investment",
            "project",
            "txn_type",
            "status",
            "currency",
            "amount",
            "occurred_on",
            "description",
            "project_name",
            "created_at",
        )


class DocumentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Document
        fields = (
            "id",
            "title",
            "category",
            "visibility",
            "original_name",
            "meta",
            "investor",
            "project",
            "investment",
            "file",
            "created_at",
        )
        read_only_fields = ("id", "original_name", "created_at")


class StatementSerializer(serializers.ModelSerializer):
    class Meta:
        model = Statement
        fields = ("id", "title", "period", "period_label", "summary", "posted_on", "document")


class NotificationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Notification
        fields = (
            "id",
            "title",
            "body",
            "kind",
            "channel",
            "status",
            "sent_at",
            "read_at",
            "created_at",
        )


class NotificationPreferenceSerializer(serializers.ModelSerializer):
    class Meta:
        model = NotificationPreference
        fields = ("email_alerts", "sms_alerts", "document_posted", "login_alerts", "whatsapp_alerts")


class TransparencyEventSerializer(serializers.ModelSerializer):
    project_name = serializers.CharField(source="project.name", read_only=True)
    project_slug = serializers.CharField(source="project.slug", read_only=True)
    project = serializers.PrimaryKeyRelatedField(queryset=Project.objects.all())

    class Meta:
        model = TransparencyEvent
        fields = (
            "id",
            "project",
            "event_type",
            "title",
            "description",
            "occurred_at",
            "progress_percent",
            "visibility",
            "period",
            "stamp_label",
            "department",
            "project_name",
            "project_slug",
            "created_at",
            "updated_at",
        )
        read_only_fields = ("id", "created_at", "updated_at", "project_name", "project_slug")


class ReportSerializer(serializers.ModelSerializer):
    project_name = serializers.CharField(source="project.name", read_only=True)

    class Meta:
        model = Report
        fields = (
            "id",
            "title",
            "report_type",
            "period_label",
            "summary",
            "visibility",
            "published_on",
            "project_name",
        )


class TicketMessageSerializer(serializers.ModelSerializer):
    author_email = serializers.EmailField(source="author.email", read_only=True)

    class Meta:
        model = TicketMessage
        fields = ("id", "body", "is_internal", "author_email", "created_at")
        read_only_fields = ("id", "is_internal", "author_email", "created_at")


class SupportTicketSerializer(serializers.ModelSerializer):
    messages = TicketMessageSerializer(many=True, read_only=True)

    class Meta:
        model = SupportTicket
        fields = (
            "id",
            "reference",
            "subject",
            "status",
            "priority",
            "created_at",
            "messages",
        )
        read_only_fields = ("id", "reference", "created_at", "messages")


class AuditLogSerializer(serializers.ModelSerializer):
    user_email = serializers.EmailField(source="user.email", read_only=True)

    class Meta:
        model = AuditLog
        fields = (
            "id",
            "user_email",
            "action",
            "module",
            "object_type",
            "object_id",
            "object_repr",
            "previous_value",
            "new_value",
            "ip_address",
            "created_at",
        )


class BeneficiarySerializer(serializers.ModelSerializer):
    project_name = serializers.CharField(source="project.name", read_only=True)

    class Meta:
        model = Beneficiary
        fields = ("id", "display_name", "public_label", "category", "benefit_type", "status", "project_name", "is_public")


class BlogPostListSerializer(serializers.ModelSerializer):
    date = serializers.DateField(source="published_on", read_only=True)

    class Meta:
        model = BlogPost
        fields = (
            "id",
            "slug",
            "title",
            "excerpt",
            "category",
            "date",
            "published_on",
            "read_time",
            "image",
            "image_alt",
            "featured",
            "is_published",
            "content",
        )
        extra_kwargs = {"published_on": {"required": False}}


class BlogPostDetailSerializer(BlogPostListSerializer):
    pass


class GalleryItemSerializer(serializers.ModelSerializer):
    id = serializers.CharField(source="code")

    class Meta:
        model = GalleryItem
        fields = ("id", "subject", "title", "caption", "src", "alt")


class ShowcaseVideoSerializer(serializers.ModelSerializer):
    id = serializers.CharField(source="code")

    class Meta:
        model = ShowcaseVideo
        fields = (
            "id",
            "category",
            "title",
            "description",
            "duration",
            "poster",
            "poster_alt",
            "youtube_id",
            "featured",
        )


class LeadershipSerializer(serializers.ModelSerializer):
    id = serializers.CharField(source="code")
    shortName = serializers.CharField(source="short_name")

    class Meta:
        model = LeadershipProfile
        fields = (
            "id",
            "role",
            "title",
            "name",
            "shortName",
            "photo",
            "signature",
            "message",
            "vision",
            "responsibilities",
            "profile",
        )


class TeamMemberSerializer(serializers.ModelSerializer):
    id = serializers.CharField(source="code")
    majorProjects = serializers.JSONField(source="major_projects")

    class Meta:
        model = TeamMember
        fields = (
            "id",
            "name",
            "position",
            "education",
            "certifications",
            "experience",
            "specialization",
            "majorProjects",
            "skills",
            "photo",
        )


class CompanyProfileSerializer(serializers.ModelSerializer):
    id = serializers.CharField(source="code")

    class Meta:
        model = CompanyProfileSection
        fields = ("id", "title", "summary", "highlights", "body", "subsections")


class ProjectInvestmentTermsSerializer(serializers.ModelSerializer):
    remaining_capacity = serializers.SerializerMethodField()
    subscribed = serializers.SerializerMethodField()

    class Meta:
        model = ProjectInvestmentTerms
        fields = (
            "id",
            "project_cost",
            "investment_pool",
            "company_contribution",
            "reserved_amount",
            "min_investment",
            "max_investment",
            "currency",
            "rule_model",
            "total_units",
            "unit_price",
            "status",
            "opens_at",
            "closes_at",
            "distribution_notes",
            "disclaimer",
            "is_published",
            "remaining_capacity",
            "subscribed",
        )

    def get_remaining_capacity(self, obj):
        from apps.investments.services import remaining_capacity

        return str(remaining_capacity(obj))

    def get_subscribed(self, obj):
        from apps.investments.models import InvestmentStatus
        from django.db.models import Sum

        total = (
            obj.project.investments.exclude(status=InvestmentStatus.CANCELLED).aggregate(total=Sum("committed_amount"))[
                "total"
            ]
            or 0
        )
        return str(total)


class InvestmentCertificateSerializer(serializers.ModelSerializer):
    class Meta:
        model = InvestmentCertificate
        fields = ("id", "certificate_number", "issued_at", "document")


class ContactInquirySerializer(serializers.ModelSerializer):
    class Meta:
        model = ContactInquiry
        fields = (
            "id",
            "name",
            "country",
            "email",
            "mobile",
            "interest",
            "investment_range",
            "message",
            "status",
            "created_at",
        )
        read_only_fields = ("id", "created_at")

    def create(self, validated_data):
        validated_data.pop("status", None)
        return super().create(validated_data)


from apps.sales.models import Customer, ProjectSale, PropertyPayment, PropertyUnit
from apps.distributions.models import (
    ApprovalRecord,
    ApprovalWorkflow,
    DistributionItem,
    ProfitCalculation,
    ProfitDistribution,
    ProjectLedgerLine,
)


class PropertyUnitSerializer(serializers.ModelSerializer):
    project_name = serializers.CharField(source="project.name", read_only=True)

    class Meta:
        model = PropertyUnit
        fields = (
            "id",
            "project",
            "project_name",
            "unit_code",
            "unit_type",
            "floor",
            "area",
            "list_price",
            "currency",
            "status",
        )


class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = ("id", "name", "email", "phone", "country", "notes", "created_at")
        read_only_fields = ("id", "created_at")


class PropertyPaymentSerializer(serializers.ModelSerializer):
    class Meta:
        model = PropertyPayment
        fields = ("id", "sale", "amount", "currency", "occurred_on", "reference", "notes", "created_at")
        read_only_fields = ("id", "created_at")


class ProjectSaleSerializer(serializers.ModelSerializer):
    unit_code = serializers.CharField(source="unit.unit_code", read_only=True)
    customer_name = serializers.CharField(source="customer.name", read_only=True)
    project_name = serializers.CharField(source="project.name", read_only=True)
    payments = PropertyPaymentSerializer(many=True, read_only=True)

    class Meta:
        model = ProjectSale
        fields = (
            "id",
            "project",
            "project_name",
            "unit",
            "unit_code",
            "customer",
            "customer_name",
            "stage",
            "contracted_amount",
            "collected_amount",
            "currency",
            "booked_at",
            "contracted_at",
            "collected_at",
            "recognized_at",
            "notes",
            "payments",
            "created_at",
        )
        read_only_fields = (
            "id",
            "collected_amount",
            "booked_at",
            "contracted_at",
            "collected_at",
            "recognized_at",
            "created_at",
        )


class LedgerLineSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProjectLedgerLine
        fields = ("id", "project", "kind", "category", "amount", "currency", "recognized", "occurred_on", "notes")


class ApprovalRecordSerializer(serializers.ModelSerializer):
    actor_email = serializers.EmailField(source="actor.email", read_only=True)

    class Meta:
        model = ApprovalRecord
        fields = ("id", "step", "decision", "actor_email", "notes", "decided_at")


class ApprovalWorkflowSerializer(serializers.ModelSerializer):
    records = ApprovalRecordSerializer(many=True, read_only=True)

    class Meta:
        model = ApprovalWorkflow
        fields = ("id", "module", "object_type", "object_id", "current_step", "status", "records", "created_at")


class DistributionItemSerializer(serializers.ModelSerializer):
    investor_code = serializers.CharField(source="investor.account_code", read_only=True)

    class Meta:
        model = DistributionItem
        fields = ("id", "investor", "investor_code", "investment", "participation_percent", "amount", "status")


class ProfitDistributionSerializer(serializers.ModelSerializer):
    items = DistributionItemSerializer(many=True, read_only=True)

    class Meta:
        model = ProfitDistribution
        fields = ("id", "project", "status", "executed_at", "items")


class ProfitCalculationSerializer(serializers.ModelSerializer):
    project_name = serializers.CharField(source="project.name", read_only=True)
    workflow = ApprovalWorkflowSerializer(read_only=True)
    distribution = ProfitDistributionSerializer(read_only=True)

    class Meta:
        model = ProfitCalculation
        fields = (
            "id",
            "project",
            "project_name",
            "sales_revenue",
            "eligible_costs",
            "distributable_profit",
            "currency",
            "status",
            "notes",
            "workflow",
            "distribution",
            "created_at",
        )
        read_only_fields = ("id", "distributable_profit", "status", "workflow", "distribution", "created_at")
