from __future__ import annotations

from sqlalchemy import String, Boolean, Integer, ForeignKey, UniqueConstraint, Text, Float, Time
from sqlalchemy.orm import Mapped, mapped_column
from app.core.db.common import CommonBase


class BranchSettings(CommonBase):
    __tablename__ = "branch_settings"
    __table_args__ = (
        UniqueConstraint("branch_id", name="uq_branch_settings_branch"),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    branch_id: Mapped[int] = mapped_column(
        ForeignKey("branches.id", ondelete="CASCADE"),
        index=True,
    )

    # Identity
    address_line1: Mapped[str | None] = mapped_column(String(255), nullable=True)
    address_line2: Mapped[str | None] = mapped_column(String(255), nullable=True)
    city: Mapped[str | None] = mapped_column(String(100), nullable=True)
    state: Mapped[str | None] = mapped_column(String(100), nullable=True)
    pin_code: Mapped[str | None] = mapped_column(String(10), nullable=True)
    gstin: Mapped[str | None] = mapped_column(String(20), nullable=True)
    pan: Mapped[str | None] = mapped_column(String(10), nullable=True)

    letterhead_logo_path: Mapped[str | None] = mapped_column(String(500), nullable=True)
    letterhead_signature_path: Mapped[str | None] = mapped_column(String(500), nullable=True)
    letterhead_stamp_path: Mapped[str | None] = mapped_column(String(500), nullable=True)

    # Geolocation and attendance controls
    geo_address: Mapped[str | None] = mapped_column(String(500), nullable=True)
    latitude: Mapped[float | None] = mapped_column(Float, nullable=True)
    longitude: Mapped[float | None] = mapped_column(Float, nullable=True)
    attendance_geo_enabled: Mapped[bool] = mapped_column(Boolean, default=False)
    attendance_geo_radius_meters: Mapped[int] = mapped_column(Integer, default=100)
    attendance_ip_enabled: Mapped[bool] = mapped_column(Boolean, default=False)
    attendance_allowed_ip_csv: Mapped[str | None] = mapped_column(Text, nullable=True)

    # Working calendar and attendance timing rules
    working_days_csv: Mapped[str] = mapped_column(String(50), default="MON,TUE,WED,THU,FRI,SAT")
    holidays_json: Mapped[str] = mapped_column(Text, default="[]")
    timezone_locked: Mapped[bool] = mapped_column(Boolean, default=False)
    attendance_grace_minutes: Mapped[int] = mapped_column(Integer, default=10)
    attendance_half_day_after_time = mapped_column(Time, nullable=True)
    attendance_rule_enabled: Mapped[bool] = mapped_column(Boolean, default=True)

    # Email policy
    email_from_name: Mapped[str | None] = mapped_column(String(200), nullable=True)
    email_from_email: Mapped[str | None] = mapped_column(String(255), nullable=True)
    email_reply_to: Mapped[str | None] = mapped_column(String(255), nullable=True)
    default_cc_csv: Mapped[str | None] = mapped_column(String(500), nullable=True)
    default_bcc_csv: Mapped[str | None] = mapped_column(String(500), nullable=True)
    email_signature_html: Mapped[str | None] = mapped_column(Text, nullable=True)

    # Phase 7Q.2 - branding / billing presentation defaults
    invoice_footer_text: Mapped[str | None] = mapped_column(Text, nullable=True)
    bank_name: Mapped[str | None] = mapped_column(String(200), nullable=True)
    bank_account_name: Mapped[str | None] = mapped_column(String(200), nullable=True)
    bank_account_number: Mapped[str | None] = mapped_column(String(50), nullable=True)
    bank_ifsc: Mapped[str | None] = mapped_column(String(20), nullable=True)
    upi_id: Mapped[str | None] = mapped_column(String(100), nullable=True)

    # Storage policy
    storage_mode: Mapped[str] = mapped_column(String(20), default="local_only")
    folder_template: Mapped[str] = mapped_column(
        String(500),
        default="{root}/Clients/{client_code}/{fy}/{service}/",
    )
    max_file_mb: Mapped[int] = mapped_column(Integer, default=25)
    allowed_ext_csv: Mapped[str] = mapped_column(
        String(500),
        default="pdf,jpg,jpeg,png,xlsx,xls,docx,zip",
    )
    retention_years: Mapped[int] = mapped_column(Integer, default=8)

    # Security policy
    otp_required_roles_csv: Mapped[str] = mapped_column(
        String(200),
        default="Partner,System Admin",
    )
    session_duration_minutes: Mapped[int] = mapped_column(Integer, default=480)
    lockout_attempts: Mapped[int] = mapped_column(Integer, default=5)
    lockout_minutes: Mapped[int] = mapped_column(Integer, default=15)