"""
data.py — a tiny synthetic corpus of "banking documents" + an evaluation set.

Why synthetic data? So the lab is self-contained, deterministic, and free of any
real customer information. In production these would be the bank's product T&Cs,
fee schedules, and policy PDFs, ingested via Azure AI Document Intelligence
(see Lab 03) and chunked into Azure AI Search (see rag.py :: AzureAISearchIndex).

Each document carries METADATA that mirrors what you would store on every chunk
in a real Azure AI Search index:
  - id        : stable identifier (used in citations as [id:section])
  - title     : human title
  - language  : "en" / "ar"  -> enables a `language` filter at query time
  - acl       : list of groups allowed to see it -> enables SECURITY TRIMMING
  - text      : the body (we chunk this in rag.py)

The EVAL set is deliberately mixed:
  - some questions need an EXACT identifier / proper noun  -> BM25 (keyword) wins
  - some questions are PARAPHRASES of the source wording    -> vector (semantic) wins
  - hybrid + semantic reranking should beat either alone.   <- the lab's thesis
"""
from __future__ import annotations
from dataclasses import dataclass, field


@dataclass
class Document:
    id: str
    title: str
    text: str
    language: str = "en"
    acl: list[str] = field(default_factory=lambda: ["retail"])


# --- The corpus -------------------------------------------------------------
# Public-bank-style content written from scratch (no real institution).
DOCUMENTS: list[Document] = [
    Document(
        "fees-current-account",
        "Current Account Fee Schedule",
        "The monthly maintenance fee for a Current Account is 25 AED. "
        "This fee is waived if the average monthly balance stays above 3000 AED. "
        "There is no charge for the first chequebook of 25 leaves. "
        "A replacement debit card costs 75 AED.",
    ),
    Document(
        "fees-transfers",
        "Transfer and Payment Fees",
        "Local transfers between accounts at the bank are free of charge. "
        "An international wire transfer (SWIFT) costs 50 AED plus correspondent bank charges. "
        "Same-day priority transfers incur an additional 25 AED. "
        "Standing orders are free to set up.",
    ),
    Document(
        "card-declines",
        "Why a Card Payment May Be Refused",
        "A card transaction can be refused for several reasons. "
        "The most common cause is insufficient available balance. "
        "Other causes include an expired card, an incorrect PIN entered three times, "
        "a daily spending limit reached, or the card being temporarily blocked for "
        "suspected fraud. If a payment fails, the customer should check the available "
        "balance and the card status in the mobile app.",
    ),
    Document(
        "dispute-policy",
        "Disputed Transaction Policy",
        "A customer may dispute a card transaction within 60 days of the statement date. "
        "To raise a dispute, the customer files a claim with the transaction reference. "
        "Provisional credit may be issued within 10 business days while the dispute is "
        "investigated. Disputes for transactions older than 60 days are not eligible.",
    ),
    Document(
        "kyc-onboarding",
        "Account Opening and KYC Requirements",
        "To open an account a customer must provide a valid Emirates ID, a passport copy, "
        "and a salary certificate or proof of income. Know Your Customer (KYC) checks "
        "include identity verification and sanctions screening. Onboarding is usually "
        "completed within two business days once all documents are received.",
    ),
    Document(
        "iban-info",
        "About Your IBAN",
        "An IBAN (International Bank Account Number) uniquely identifies your account for "
        "transfers. A UAE IBAN has 23 characters beginning with the country code AE. "
        "You can find your IBAN on your statement, in the mobile app, or by contacting "
        "the bank. Always double-check the IBAN before sending a transfer.",
    ),
    Document(
        "loan-rates",
        "Personal Loan Indicative Rates",
        "Personal loans are offered at a reducing-balance interest rate starting from "
        "5.99% per annum for salaried customers. The maximum tenure is 48 months. "
        "Early settlement is permitted with a 1% early-settlement fee on the outstanding "
        "balance. Approval is subject to eligibility and a minimum salary of 8000 AED.",
    ),
    Document(
        "mobile-app",
        "Mobile App Features",
        "The mobile banking app lets you view balances, transfer funds, pay bills, freeze "
        "and unfreeze your card, view your IBAN, and raise transaction disputes. "
        "Biometric login (fingerprint or face) is supported. The app is available in "
        "English and Arabic.",
    ),
    Document(
        "islamic-murabaha",
        "Islamic Banking: Murabaha Explained",
        "Murabaha is a Sharia-compliant financing structure where the bank buys an asset "
        "and sells it to the customer at a disclosed profit margin, payable in instalments. "
        "Unlike a conventional loan there is no interest (riba); the bank's profit is the "
        "agreed mark-up. Murabaha is commonly used for car and home financing.",
    ),
    Document(
        "statements",
        "Account Statements",
        "Monthly account statements are generated on the first day of each month and cover "
        "the previous calendar month. Statements list the opening balance, all transactions, "
        "and the closing balance. You can download statements as PDF from the app for the "
        "last 24 months. Paper statements can be requested for 10 AED each.",
    ),
    # An Arabic document (different ACL group) to exercise language filtering + security trimming.
    Document(
        "fees-current-account-ar",
        "جدول رسوم الحساب الجاري",
        "الرسم الشهري لصيانة الحساب الجاري هو 25 درهماً ويُعفى منه إذا تجاوز متوسط الرصيد "
        "الشهري 3000 درهم. دفتر الشيكات الأول مجاني.",
        language="ar",
        acl=["retail"],
    ),
    # A staff-only document — a 'retail' user must NOT be able to retrieve this.
    Document(
        "internal-override",
        "Internal: Fee Override Procedure (STAFF ONLY)",
        "Branch staff may waive the current account maintenance fee at their discretion for "
        "relationship customers using override code OVR-204. This procedure is confidential "
        "and must not be disclosed to customers.",
        language="en",
        acl=["staff"],
    ),
]


# --- The evaluation set -----------------------------------------------------
@dataclass
class EvalCase:
    question: str
    expected_doc: str      # the document id that should be retrieved
    key_fact: str          # a substring the correct answer should contain
    kind: str              # "keyword" | "semantic" | "mixed" — for analysis only


EVAL: list[EvalCase] = [
    EvalCase("What is the monthly fee for a current account?", "fees-current-account", "25", "mixed"),
    EvalCase("How do I get the current account maintenance fee waived?", "fees-current-account", "3000", "semantic"),
    EvalCase("How much does an international SWIFT wire transfer cost?", "fees-transfers", "50", "keyword"),
    EvalCase("Are local transfers free?", "fees-transfers", "free", "mixed"),
    EvalCase("My card payment was refused — why might that happen?", "card-declines", "balance", "semantic"),
    EvalCase("Why would a transaction fail at the point of sale?", "card-declines", "balance", "semantic"),
    EvalCase("How long do I have to dispute a transaction?", "dispute-policy", "60 days", "mixed"),
    EvalCase("When is provisional credit issued for a dispute?", "dispute-policy", "10 business days", "semantic"),
    EvalCase("What documents do I need to open an account?", "kyc-onboarding", "Emirates ID", "mixed"),
    EvalCase("How many characters is a UAE IBAN?", "iban-info", "23", "keyword"),
    EvalCase("Where can I find my IBAN?", "iban-info", "statement", "semantic"),
    EvalCase("What is the starting interest rate on a personal loan?", "loan-rates", "5.99", "keyword"),
    EvalCase("Is there a penalty for paying off my loan early?", "loan-rates", "1%", "semantic"),
    EvalCase("Can I freeze my card in the app?", "mobile-app", "freeze", "mixed"),
    EvalCase("What is Murabaha?", "islamic-murabaha", "profit", "keyword"),
    EvalCase("Does Islamic financing charge interest?", "islamic-murabaha", "riba", "semantic"),
    EvalCase("When are monthly statements generated?", "statements", "first day", "mixed"),
    EvalCase("How far back can I download statements?", "statements", "24 months", "keyword"),
    EvalCase("How much is a paper statement?", "statements", "10", "keyword"),
    EvalCase("Can I get my account fee waived by talking to a branch?", "internal-override", "", "semantic"),
    # ^ last case: the answer lives in a STAFF-ONLY doc; a retail user should get an
    #   abstention, NOT the override code. This tests security trimming + abstention.
]
