from __future__ import annotations

import logging
from datetime import datetime
from typing import Any

logger = logging.getLogger(__name__)


class ErpDocumentReadMixin:
    def list_documents(
        self,
        category: str | None = None,
        document_group: str | None = None,
        document_type: str | None = None,
        project_id: str | None = None,
        project_stage: str | None = None,
        signature_status: str | None = None,
        quarantine_status: str | None = None,
        active_only: bool = True,
        search: str | None = None,
        year: int | None = None,
        limit: int | None = None,
        offset: int = 0,
    ) -> list[dict[str, Any]]:
        """Lấy danh sách văn bản theo các bộ lọc giai đoạn, nhóm, loại văn bản, trạng thái ký, năm và phân trang."""
        sql = """
            SELECT d.*, p.project_name, count(*) OVER() as full_count
            FROM erp_documents d
            LEFT JOIN projects p ON d.project_id = p.id
            WHERE 1=1
        """
        params: list[Any] = []
        if active_only:
            sql += " AND d.is_active_version = TRUE"
        if category and category != "all":
            sql += " AND (d.category = %s OR d.document_direction = %s OR d.document_group = %s)"
            params.extend([category, category, category])
        if document_group and document_group != "all":
            sql += " AND d.document_group = %s"
            params.append(document_group)
        if document_type and document_type != "all":
            sql += " AND d.document_type = %s"
            params.append(document_type)
        if project_stage and project_stage != "all":
            sql += " AND d.project_stage = %s"
            params.append(project_stage)
        if signature_status and signature_status != "all":
            sql += " AND d.signature_status = %s"
            params.append(signature_status)
        if quarantine_status and quarantine_status != "all":
            sql += " AND d.quarantine_status = %s"
            params.append(quarantine_status)
        if project_id and project_id != "all":
            sql += " AND (d.project_id::text = %s OR p.project_code = %s)"
            params.extend([project_id, project_id])
        if year:
            sql += " AND EXTRACT(YEAR FROM d.issue_date) = %s"
            params.append(year)
        if search:
            sql += """ AND (
                d.document_code ILIKE %s 
                OR d.document_title ILIKE %s 
                OR d.issuer_name ILIKE %s 
                OR d.partner_name ILIKE %s
                OR d.summary_content ILIKE %s
                OR d.signer_name ILIKE %s
                OR d.partner_tax_code ILIKE %s
            )"""
            pattern = f"%{search.strip()}%"
            params.extend(
                [pattern, pattern, pattern, pattern, pattern, pattern, pattern]
            )

        sql += " ORDER BY d.issue_date DESC NULLS LAST, d.created_at DESC"
        if limit is not None:
            sql += " LIMIT %s OFFSET %s"
            params.extend([limit, offset])
        sql += ";"

        with self.get_connection() as conn, conn.cursor() as cur:
            cur.execute(sql, params)
            return cur.fetchall()

    def get_document(self, doc_id: str) -> dict[str, Any] | None:
        """Lấy thông tin chi tiết một văn bản theo id."""
        import uuid

        try:
            uuid.UUID(str(doc_id))
        except (ValueError, AttributeError):
            return None

        sql = """
            SELECT d.*, p.project_name
            FROM erp_documents d
            LEFT JOIN projects p ON d.project_id = p.id
            WHERE d.id = %s;
        """
        with self.get_connection() as conn, conn.cursor() as cur:
            cur.execute(sql, (doc_id,))
            return cur.fetchone()

    def get_next_document_code(
        self, doc_type: str, year: int | None = None
    ) -> dict[str, Any]:
        """Lấy số văn bản kế tiếp theo loại văn bản và năm hiện tại."""
        if not year:
            year = datetime.now().year
        doc_type = doc_type.upper().strip()

        with self.get_connection() as conn, conn.cursor() as cur:
            # Đếm số văn bản cùng loại trong năm để sinh mã số tiếp theo
            cur.execute(
                """
                    SELECT count(*) FROM erp_documents
                    WHERE document_type = %s AND EXTRACT(YEAR FROM issue_date) = %s;
                """,
                (doc_type, year),
            )
            row = cur.fetchone()
            current_num = row["count"] if row else 0
            next_num = current_num + 1
            next_code = f"{next_num:02d}/{year}/{doc_type}-ĐS"

            return {
                "doc_type": doc_type,
                "year": year,
                "next_number": next_num,
                "next_code": next_code,
            }

    def _ensure_document_columns(self) -> None:
        """Đảm bảo bảng erp_documents có đầy đủ cột file_hash và các chỉ mục phục vụ phát hiện trùng lặp."""
        sql = """
            ALTER TABLE erp_documents
            ADD COLUMN IF NOT EXISTS file_hash VARCHAR(64);
            CREATE INDEX IF NOT EXISTS idx_erp_documents_file_hash ON erp_documents(file_hash);
        """
        try:
            with self.get_connection() as conn, conn.cursor() as cur:
                cur.execute(sql)
                conn.commit()
        except Exception:
            pass
