# -*- coding: utf-8 -*-
"""STEP 5 — Mandatory disclosure (Florida Family Law Rule 12.285).

Three models, all hanging off a PROCEEDING:

  * familylaw.disclosure.item   — the checklist of required disclosure documents
  * familylaw.financial.affidavit — the financial affidavit, with the form-by-income
                                    selection (12.902(b) short vs 12.902(c) long)
  * familylaw.fin.line          — line items (income/expense/asset/liability)

LEGAL NOTES (verify current rule — these values are volatile):
  * Mandatory disclosure under Rule 12.285 CANNOT be waived by the parties (with
    narrow exceptions, e.g. simplified dissolution). Items flagged is_mandatory
    refuse waiver in code.
  * The financial affidavit form turns on gross annual income: below the threshold
    the short form 12.902(b) applies; at or above it the long form 12.902(c) applies.
    The threshold is currently $50,000 — CONFIRM before relying on it.
  * The affidavit is due within 45 days of service of the initial pleading
    (Rule 12.285(e)) — confirm the trigger and count for the matter at hand.
"""

from datetime import timedelta

from odoo import api, fields, models, _
from odoo.exceptions import UserError

# VERIFY CURRENT RULE — do not treat as permanent.
DISCLOSURE_INCOME_THRESHOLD = 50000.0   # gross annual income, USD
DISCLOSURE_DUE_DAYS = 45                 # Rule 12.285(e)


def _roll_forward_weekend(due):
    while due.weekday() >= 5:
        due += timedelta(days=1)
    return due


class FamilyLawDisclosureItem(models.Model):
    _name = "familylaw.disclosure.item"
    _description = "Mandatory Disclosure Item"
    _inherit = ["mail.thread", "mail.activity.mixin"]
    _order = "sequence, id"

    sequence = fields.Integer(default=10)
    proceeding_id = fields.Many2one(
        "familylaw.proceeding", required=True, ondelete="cascade", index=True,
        tracking=True,
    )
    case_id = fields.Many2one(
        "familylaw.case", related="proceeding_id.case_id", store=True, index=True,
    )
    name = fields.Char(required=True, tracking=True)
    is_mandatory = fields.Boolean(
        string="Mandatory (cannot waive)",
        default=True,
        help="Rule 12.285 disclosure that the parties cannot waive.",
    )
    state = fields.Selection(
        selection=[
            ("required", "Required"),
            ("provided", "Provided"),
            ("waived", "Waived"),
            ("na", "Not Applicable"),
        ],
        default="required",
        required=True,
        tracking=True,
    )
    notes = fields.Text()

    def action_mark_provided(self):
        for item in self:
            item.state = "provided"
            item.message_post(body=_("Disclosure item provided."))
        return True

    def action_waive(self):
        for item in self:
            if item.is_mandatory:
                raise UserError(
                    _("'%s' is mandatory disclosure under Rule 12.285 and cannot be "
                      "waived by the parties.") % item.name
                )
            item.state = "waived"
            item.message_post(body=_("Disclosure item waived (non-mandatory)."))
        return True


class FamilyLawFinancialAffidavit(models.Model):
    _name = "familylaw.financial.affidavit"
    _description = "Financial Affidavit (12.902(b)/(c))"
    _inherit = ["mail.thread", "mail.activity.mixin"]
    _order = "create_date desc"

    proceeding_id = fields.Many2one(
        "familylaw.proceeding", required=True, ondelete="cascade", index=True,
        tracking=True,
    )
    case_id = fields.Many2one(
        "familylaw.case", related="proceeding_id.case_id", store=True, index=True,
    )
    party_id = fields.Many2one("familylaw.party", string="Affiant (party)")
    name = fields.Char(string="Affiant Name", required=True, tracking=True)

    gross_annual_income = fields.Float(
        string="Gross Annual Income",
        tracking=True,
        help="Drives the form selection. Verify the current threshold.",
    )
    form_type = fields.Selection(
        selection=[
            ("short", "Short Form — 12.902(b)"),
            ("long", "Long Form — 12.902(c)"),
        ],
        compute="_compute_form_type",
        store=True,
        string="Required Form",
    )
    form_reference = fields.Char(
        compute="_compute_form_type", store=True, string="Form #",
    )

    trigger_date = fields.Date(string="Trigger (service) Date", tracking=True)
    due_date = fields.Date(
        compute="_compute_due_date", store=True, tracking=True,
        help="45 days from the trigger (Rule 12.285(e)), rolled off weekends.",
    )
    state = fields.Selection(
        selection=[
            ("draft", "Draft"),
            ("provided", "Provided"),
            ("filed", "Filed"),
        ],
        default="draft",
        required=True,
        tracking=True,
    )
    line_ids = fields.One2many(
        "familylaw.fin.line", "affidavit_id", string="Line Items",
    )
    total_income = fields.Float(compute="_compute_totals", store=True)
    total_expense = fields.Float(compute="_compute_totals", store=True)
    total_asset = fields.Float(compute="_compute_totals", store=True)
    total_liability = fields.Float(compute="_compute_totals", store=True)
    net_worth = fields.Float(compute="_compute_totals", store=True)

    @api.depends("gross_annual_income")
    def _compute_form_type(self):
        for aff in self:
            if aff.gross_annual_income >= DISCLOSURE_INCOME_THRESHOLD:
                aff.form_type = "long"
                aff.form_reference = "12.902(c)"
            else:
                aff.form_type = "short"
                aff.form_reference = "12.902(b)"

    @api.depends("trigger_date")
    def _compute_due_date(self):
        for aff in self:
            if not aff.trigger_date:
                aff.due_date = False
                continue
            raw = aff.trigger_date + timedelta(days=DISCLOSURE_DUE_DAYS)
            aff.due_date = _roll_forward_weekend(raw)

    @api.depends("line_ids.amount", "line_ids.category")
    def _compute_totals(self):
        for aff in self:
            sums = {"income": 0.0, "expense": 0.0, "asset": 0.0, "liability": 0.0}
            for line in aff.line_ids:
                if line.category in sums:
                    sums[line.category] += line.amount
            aff.total_income = sums["income"]
            aff.total_expense = sums["expense"]
            aff.total_asset = sums["asset"]
            aff.total_liability = sums["liability"]
            aff.net_worth = sums["asset"] - sums["liability"]

    def action_mark_provided(self):
        for aff in self:
            aff.state = "provided"
            aff.message_post(body=_("Financial affidavit provided."))
        return True


class FamilyLawFinLine(models.Model):
    _name = "familylaw.fin.line"
    _description = "Financial Affidavit Line"
    _order = "category, id"

    affidavit_id = fields.Many2one(
        "familylaw.financial.affidavit", required=True, ondelete="cascade", index=True,
    )
    category = fields.Selection(
        selection=[
            ("income", "Income"),
            ("expense", "Expense"),
            ("asset", "Asset"),
            ("liability", "Liability"),
        ],
        required=True,
        default="income",
    )
    name = fields.Char(string="Description", required=True)
    amount = fields.Float()
    monthly = fields.Boolean(
        string="Monthly?",
        help="If set, this is a recurring monthly figure (informational).",
    )
