"""Build ERP login cards for WhatsApp delivery."""
from __future__ import annotations

import secrets
import string
from typing import Any, Dict, Optional, Tuple

from sqlalchemy.orm import Session

from app.core.config import settings
from app.models.branch import Branch
from app.models.company import Company
from app.models.user import User
from app.services.cloud_sync_service import load_node_config, is_lan_sync_client


def generate_temp_password(length: int = 12) -> str:
    alphabet = string.ascii_letters + string.digits
    return "".join(secrets.choice(alphabet) for _ in range(length))


def resolve_login_url(db: Session, company: Optional[Company]) -> str:
    dep = (settings.deployment_mode or "cloud").lower()
    if dep in ("local", "hybrid"):
        cfg = load_node_config()
        cloud = (cfg.get("cloud_url") or settings.license_cloud_url or settings.erp_public_url or "").rstrip("/")
        if cloud:
            return f"{cloud}/static/login.html"
    base = (settings.erp_public_url or settings.license_cloud_url or "").rstrip("/")
    if not base and company:
        base = (settings.erp_public_url or "").rstrip("/")
    return f"{base}/static/login.html" if base else "/static/login.html"


def build_login_card(
    *,
    login_url: str,
    company: Company,
    branch: Optional[Branch],
    user: User,
    password_plain: Optional[str] = None,
    custom_note: Optional[str] = None,
    is_cloud_target: bool = False,
) -> str:
    lines = [
        "CNP ERP — Login details",
        "",
        f"URL: {login_url}",
    ]
    if is_cloud_target or (settings.deployment_mode or "cloud").lower() == "cloud":
        lines.append(f"Company code: {company.company_code}")
        lines.append(f"Company: {company.name}")
    if branch:
        lines.append(f"Branch code: {branch.code}")
        lines.append(f"Branch: {branch.name}")
    lines.extend([
        f"Username: {user.username}",
    ])
    if password_plain:
        lines.append(f"Temporary password: {password_plain}")
        lines.append("(Change this password after your first sign-in.)")
    else:
        lines.append("Password: use the password your administrator set for you.")
    if custom_note:
        lines.extend(["", custom_note])
    lines.extend(["", "— CNP ERP"])
    return "\n".join(lines)


def gather_login_context(
    db: Session,
    *,
    user: User,
    company_id: Optional[str],
    branch_id: Optional[str] = None,
    prefer_cloud: bool = False,
) -> Tuple[Company, Optional[Branch], str, bool]:
    cid = company_id or user.company_id
    if not cid:
        raise ValueError("No company context for login card.")
    company = db.query(Company).filter(Company.id == cid).first()
    if not company:
        raise ValueError("Company not found.")

    branch = None
    if branch_id:
        branch = db.query(Branch).filter(Branch.id == branch_id, Branch.company_id == company.id).first()
    elif user.branch_id:
        branch = db.query(Branch).filter(Branch.id == user.branch_id).first()
    if not branch:
        branch = (
            db.query(Branch)
            .filter(Branch.company_id == company.id, Branch.is_head_office == True, Branch.active == True)
            .first()
        )
    if not branch:
        branch = db.query(Branch).filter(Branch.company_id == company.id, Branch.active == True).first()

    is_cloud = prefer_cloud or (settings.deployment_mode or "cloud").lower() == "cloud"
    login_url = resolve_login_url(db, company)
    if prefer_cloud and is_lan_sync_client():
        cfg = load_node_config()
        cloud = (cfg.get("cloud_url") or settings.license_cloud_url or settings.erp_public_url or "").rstrip("/")
        if cloud:
            login_url = f"{cloud}/static/login.html"
            is_cloud = True
    return company, branch, login_url, is_cloud


def build_login_message_for_user(
    db: Session,
    *,
    user: User,
    company_id: Optional[str],
    password_plain: Optional[str] = None,
    custom_note: Optional[str] = None,
    prefer_cloud: bool = False,
    branch_id: Optional[str] = None,
) -> Dict[str, Any]:
    company, branch, login_url, is_cloud = gather_login_context(
        db,
        user=user,
        company_id=company_id,
        branch_id=branch_id,
        prefer_cloud=prefer_cloud,
    )
    message = build_login_card(
        login_url=login_url,
        company=company,
        branch=branch,
        user=user,
        password_plain=password_plain,
        custom_note=custom_note,
        is_cloud_target=is_cloud,
    )
    return {
        "message": message,
        "login_url": login_url,
        "company_code": company.company_code,
        "branch_code": branch.code if branch else None,
        "username": user.username,
    }
