from __future__ import annotations

from rest_framework import views
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from basic_info import models as basic_models
from business import services as business_services
from api_v1.views.stock_change_views.mixins import StockChangeViewMixin

from . import serializers as statement_serializers


class StatementViewBase(StockChangeViewMixin, views.APIView):
    """
    提供对账单视图的公共实现：权限校验、序列化上下文及响应构造。
    """

    permission_classes = [IsAuthenticated]
    serializer_class = statement_serializers.StatementResponseSerializer

    def get_serializer_context(self):
        return {
            'request': self.request,
            'view': self,
            'summary_builder': business_services.build_statement_summary,
        }

    def _build_response(self, payload: dict):
        serializer = self.serializer_class(
            instance=payload,
            context=self.get_serializer_context(),
        )
        return Response(serializer.data)


class CustomerStatementView(StatementViewBase):
    """
    返回指定客户的业务单据对账单，包含销售单、销售退货单与收款单。
    """

    def get(self, request, customer_id: int):
        if not self.check_employee_permission(request):
            return self.permission_error_response('无权限访问')

        merchant = request.user.employee.merchant
        try:
            customer = basic_models.Customer.objects.get(id=customer_id, merchant=merchant)
        except basic_models.Customer.DoesNotExist:
            return self.not_found_response('客户不存在')

        payload = business_services.build_customer_statement(merchant=merchant, customer=customer)
        return self._build_response(payload)


class SupplierStatementView(StatementViewBase):
    """
    返回指定供应商的业务单据对账单，包含采购单、采购退货单与付款单。
    """

    def get(self, request, supplier_id: int):
        if not self.check_employee_permission(request):
            return self.permission_error_response('无权限访问')

        merchant = request.user.employee.merchant
        try:
            supplier = basic_models.Supplier.objects.get(id=supplier_id, merchant=merchant)
        except basic_models.Supplier.DoesNotExist:
            return self.not_found_response('供应商不存在')

        payload = business_services.build_supplier_statement(merchant=merchant, supplier=supplier)
        return self._build_response(payload)


class StatementRecordView(StatementViewBase):
    """
    根据业务主体与单据信息查询单条对账记录，返回与列表接口一致的 schema。
    """

    def get(self, request):
        if not self.check_employee_permission(request):
            return self.permission_error_response('无权限访问')

        serializer = statement_serializers.StatementRecordQuerySerializer(data=request.query_params)
        serializer.is_valid(raise_exception=True)
        params = serializer.validated_data

        merchant = request.user.employee.merchant
        counterparty_type = params['counterparty_type']
        counterparty_id = params['counterparty_id']
        order_type = params['order_type']
        order_id = params['order_id']

        if counterparty_type == 'customer':
            try:
                counterparty = basic_models.Customer.objects.get(id=counterparty_id, merchant=merchant)
            except basic_models.Customer.DoesNotExist:
                return self.not_found_response('客户不存在')
            payload = business_services.build_customer_statement(merchant=merchant, customer=counterparty)
        else:
            try:
                counterparty = basic_models.Supplier.objects.get(id=counterparty_id, merchant=merchant)
            except basic_models.Supplier.DoesNotExist:
                return self.not_found_response('供应商不存在')
            payload = business_services.build_supplier_statement(merchant=merchant, supplier=counterparty)

        matched_records = [
            record
            for record in payload.get('records', [])
            if record['source_type'] == order_type and record['source_id'] == order_id
        ]

        if not matched_records:
            return self.not_found_response('未找到匹配的对账记录')

        single_payload = {
            'counterparty': payload['counterparty'],
            'counterparty_name': payload['counterparty_name'],
            'records': matched_records,
        }
        return self._build_response(single_payload)
