from __future__ import annotations

from datetime import date, datetime, time

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


class Tenant(CommonBase):
    __tablename__ = "tenants"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    code: Mapped[str] = mapped_column(String(50), unique=True, index=True)
    name: Mapped[str] = mapped_column(String(200))
    is_active: Mapped[bool] = mapped_column(Boolean, default=True)
    firm_type: Mapped[str] = mapped_column(String(30), default="proprietorship")  # partnership|proprietorship|individual

    # Tenant-level defaults
    default_timezone: Mapped[str] = mapped_column(String(64), default="Asia/Kolkata")
    default_session_duration_minutes: Mapped[int] = mapped_column(Integer, default=480)
    default_otp_required_roles_csv: Mapped[str] = mapped_column(
        String(200),
        default="Partner,System Admin",
    )
    default_storage_mode: Mapped[str] = mapped_column(
        String(20),
        default="local_only",
    )  # local_only|cloud_only|hybrid

    # Phase 7Q.2 - firm branding defaults
    display_name: Mapped[str | None] = mapped_column(String(200), nullable=True)
    logo_path: Mapped[str | None] = mapped_column(String(500), nullable=True)
    favicon_path: Mapped[str | None] = mapped_column(String(500), nullable=True)
    primary_color: Mapped[str | None] = mapped_column(String(20), nullable=True)
    accent_color: Mapped[str | None] = mapped_column(String(20), nullable=True)
    website_url: Mapped[str | None] = mapped_column(String(255), nullable=True)
    contact_email: Mapped[str | None] = mapped_column(String(255), nullable=True)
    contact_mobile: Mapped[str | None] = mapped_column(String(50), nullable=True)


class Branch(CommonBase):
    __tablename__ = "branches"
    __table_args__ = (
        UniqueConstraint("tenant_id", "code", name="uq_branch_tenant_code"),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    tenant_id: Mapped[int] = mapped_column(
        ForeignKey("tenants.id", ondelete="CASCADE"),
        index=True,
    )
    code: Mapped[str] = mapped_column(String(50), index=True)
    name: Mapped[str] = mapped_column(String(200))
    is_active: Mapped[bool] = mapped_column(Boolean, default=True)

    timezone: Mapped[str] = mapped_column(String(64), default="Asia/Kolkata")
    office_start_time: Mapped[time | None] = mapped_column(Time, nullable=True)
    office_end_time: Mapped[time | None] = mapped_column(Time, nullable=True)

    # Branch control flags
    allow_login: Mapped[bool] = mapped_column(Boolean, default=True)
    allow_new_assignments: Mapped[bool] = mapped_column(Boolean, default=True)
    is_head_office: Mapped[bool] = mapped_column(Boolean, default=False)

    # SMTP (credentials here; policy in BranchSettings)
    smtp_host: Mapped[str | None] = mapped_column(String(255), nullable=True)
    smtp_port: Mapped[int | None] = mapped_column(Integer, nullable=True)
    smtp_username: Mapped[str | None] = mapped_column(String(255), nullable=True)
    smtp_password: Mapped[str | None] = mapped_column(String(255), nullable=True)
    smtp_use_tls: Mapped[bool] = mapped_column(Boolean, default=True)

    # Local storage root for branch PC
    local_storage_path: Mapped[str | None] = mapped_column(String(500), nullable=True)

class FinancialYear(CommonBase):
    __tablename__ = "financial_years"
    __table_args__ = (
        UniqueConstraint("tenant_id", "year_code", name="uq_financial_year_tenant_code"),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    tenant_id: Mapped[int] = mapped_column(
        ForeignKey("tenants.id", ondelete="CASCADE"),
        index=True,
    )
    year_code: Mapped[str] = mapped_column(String(9), index=True)  # e.g. 2025-26
    assessment_year: Mapped[str] = mapped_column(String(9), index=True)  # e.g. 2026-27
    start_date: Mapped[date] = mapped_column(Date)
    end_date: Mapped[date] = mapped_column(Date)
    is_current: Mapped[bool] = mapped_column(Boolean, default=False, index=True)
    is_locked: Mapped[bool] = mapped_column(Boolean, default=False, index=True)
    locked_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
    locked_by_user_id: Mapped[int | None] = mapped_column(
        ForeignKey("users.id", ondelete="SET NULL"),
        nullable=True,
        index=True,
    )
    created_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=datetime.utcnow)
    updated_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=datetime.utcnow, onupdate=datetime.utcnow)


class YearBackupExport(CommonBase):
    __tablename__ = "year_backup_exports"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    tenant_id: Mapped[int] = mapped_column(
        ForeignKey("tenants.id", ondelete="CASCADE"),
        index=True,
    )
    financial_year_id: Mapped[int] = mapped_column(
        ForeignKey("financial_years.id", ondelete="CASCADE"),
        index=True,
    )
    year_code: Mapped[str] = mapped_column(String(9), index=True)
    assessment_year: Mapped[str | None] = mapped_column(String(9), nullable=True, index=True)
    export_status: Mapped[str] = mapped_column(String(30), default="completed", index=True)
    export_file_path: Mapped[str] = mapped_column(String(1000))
    file_size_bytes: Mapped[int] = mapped_column(Integer, default=0)
    manifest_json: Mapped[str | None] = mapped_column(Text, nullable=True)
    generated_by_user_id: Mapped[int | None] = mapped_column(
        ForeignKey("users.id", ondelete="SET NULL"),
        nullable=True,
        index=True,
    )
    generated_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=datetime.utcnow)
