"""Receipt and ReceiptAttachment SQLModel models."""

from datetime import datetime, date
from decimal import Decimal
from enum import Enum
from typing import Optional, List, TYPE_CHECKING

from sqlmodel import SQLModel, Field, Relationship


class ReceiptType(str, Enum):
    """Type of receipt document."""
    BON_FISCAL = "bon_fiscal"
    CHITANTA = "chitanta"


class ReceiptDirection(str, Enum):
    """Direction of receipt - expense or income."""
    CHELTUIALA = "cheltuiala"  # Expense (receipt from supplier)
    INCASARE = "incasare"      # Income (receipt issued to client)


class ReceiptStatus(str, Enum):
    """Workflow status of receipt."""
    DRAFT = "draft"                    # User is filling in data
    PENDING_REVIEW = "pending_review"  # Awaiting accountant approval
    APPROVED = "approved"              # Approved by accountant
    REJECTED = "rejected"              # Rejected by accountant
    SYNCED = "synced"                  # Synced to Oracle (Phase 2)


class PaymentMode(str, Enum):
    """Payment mode - how the expense was paid."""
    CASA = "casa"                        # Numerar firma (5311)
    BANCA = "banca"                      # Virament/POS (5121)
    AVANS_DECONTARE = "avans_decontare"  # Decont angajat (542)


class ProcessingStatus(str, Enum):
    """Processing status for bulk uploaded receipts."""
    PENDING = "pending"          # Waiting in queue
    PROCESSING = "processing"    # Currently being processed by OCR
    COMPLETED = "completed"      # Successfully processed
    FAILED = "failed"            # Processing failed with error


if TYPE_CHECKING:
    from .accounting_entry import AccountingEntry


class Receipt(SQLModel, table=True):
    """Receipt (Bon Fiscal / Chitanta) with approval workflow."""

    __tablename__ = "receipts"

    id: Optional[int] = Field(default=None, primary_key=True)

    # Document identification
    receipt_type: ReceiptType = Field(default=ReceiptType.BON_FISCAL)
    direction: ReceiptDirection = Field(default=ReceiptDirection.CHELTUIALA)
    receipt_number: Optional[str] = Field(default=None, max_length=50)
    receipt_series: Optional[str] = Field(default=None, max_length=20)

    # Main data
    receipt_date: date
    amount: Decimal = Field(decimal_places=2, max_digits=15)
    description: Optional[str] = Field(default=None, max_length=500)

    # TVA info (extracted from OCR) - stored as JSON for multiple entries
    tva_breakdown: Optional[str] = Field(default=None, max_length=1000)  # JSON: [{"code":"A","percent":19,"amount":"15.20"}]
    tva_total: Optional[Decimal] = Field(default=None, decimal_places=2, max_digits=15)
    items_count: Optional[int] = Field(default=None)
    vendor_address: Optional[str] = Field(default=None, max_length=500)

    # Expense type (for auto-generating accounting entries)
    expense_type_code: Optional[str] = Field(default=None, max_length=20)

    # Oracle references (nomenclatures)
    company_id: int
    # partner_id removed - supplier data is text-only (partner_name, cui)
    partner_name: Optional[str] = Field(default=None, max_length=200)  # Supplier name from OCR/selection
    cui: Optional[str] = Field(default=None, max_length=20)  # Fiscal code from OCR
    ocr_raw_text: Optional[str] = Field(default=None)  # Raw OCR text for debugging
    payment_methods: Optional[str] = Field(default=None, max_length=500)  # JSON: [{"method":"CARD","amount":"50.00"}]
    cash_register_id: Optional[int] = Field(default=None)  # Cash/Bank ID from Oracle
    cash_register_name: Optional[str] = Field(default=None, max_length=100)  # Cache for display
    cash_register_account: Optional[str] = Field(default=None, max_length=20)  # Account code (5311, 5121)
    payment_mode: Optional[str] = Field(default=None, max_length=20)  # PaymentMode value: casa/banca/avans_decontare

    # Workflow
    status: ReceiptStatus = Field(default=ReceiptStatus.DRAFT)
    created_by: str = Field(max_length=100)  # Username of creator
    created_at: datetime = Field(default_factory=datetime.utcnow)
    updated_at: datetime = Field(default_factory=datetime.utcnow)
    submitted_at: Optional[datetime] = Field(default=None)  # When submitted for approval

    # Approval
    reviewed_by: Optional[str] = Field(default=None, max_length=100)  # Accountant username
    reviewed_at: Optional[datetime] = Field(default=None)
    rejection_reason: Optional[str] = Field(default=None, max_length=500)  # Reason for rejection

    # Phase 2 - Oracle sync
    oracle_synced_at: Optional[datetime] = Field(default=None)
    oracle_act_id: Optional[int] = Field(default=None)
    oracle_error: Optional[str] = Field(default=None, max_length=500)

    # Bulk upload batch tracking
    batch_id: Optional[str] = Field(default=None, max_length=50, index=True)
    processing_status: Optional[str] = Field(default=None, max_length=20, index=True)  # ProcessingStatus enum value
    processing_error: Optional[str] = Field(default=None)  # Full error message text
    file_hash: Optional[str] = Field(default=None, max_length=64, index=True)  # SHA-256 hash for duplicate detection
    processing_started_at: Optional[datetime] = Field(default=None)
    processing_completed_at: Optional[datetime] = Field(default=None)

    # Relationships
    attachments: List["ReceiptAttachment"] = Relationship(
        back_populates="receipt",
        sa_relationship_kwargs={"cascade": "all, delete-orphan"}
    )
    entries: List["AccountingEntry"] = Relationship(
        back_populates="receipt",
        sa_relationship_kwargs={"cascade": "all, delete-orphan"}
    )


class ReceiptAttachment(SQLModel, table=True):
    """Attachment (photo or PDF) for a receipt."""

    __tablename__ = "receipt_attachments"

    id: Optional[int] = Field(default=None, primary_key=True)
    receipt_id: int = Field(foreign_key="receipts.id", index=True)

    # File info
    filename: str = Field(max_length=255)  # Original filename
    stored_filename: str = Field(max_length=255)  # Filename on disk (UUID)
    file_path: str = Field(max_length=500)  # Relative path
    file_size: int  # Size in bytes
    mime_type: str = Field(max_length=100)  # MIME type (image/jpeg, application/pdf)
    uploaded_at: datetime = Field(default_factory=datetime.utcnow)

    # Relationship
    receipt: Optional[Receipt] = Relationship(back_populates="attachments")
