-- t-paliad-094: Tier 2 Fristenrechner rule ports.
--
-- Audit recommendations §6.2 (rec 5-9): port a high-value subset of youpc
-- deadlines into the proceeding-tree (timeline) Fristenrechner. These rules
-- already exist in paliad.event_deadlines (imported PR-1 / migration 028),
-- so they're surfaceable today via the trigger-event mode. This migration
-- makes them surfaceable in course-of-proceedings (timeline) mode.
--
-- 14 rules ported across 5 families:
--
--   5. Damages determination (3 rules)
--      RoP.137.2 (Defence to damages, 2mo)
--      RoP.139   (Reply 1mo)
--      RoP.139   (Rejoinder 1mo)
--      → new UPC_DAMAGES proceeding type
--
--   6. Cost-decision appeals (2 rules)
--      RoP.151   (Cost decision app, 1mo) → UPC_INF extension
--      RoP.221.1 (Leave-to-appeal cost decision, 15d)
--      → new UPC_COST_APPEAL proceeding type
--
--   7. Statement-of-Appeal "with leave" / discretionary review (2 rules)
--      RoP.220.2 (Appeal Orders & with leave, 15d)
--      RoP.220.3 (Discretionary review, 15d)
--      → new UPC_APP_ORDERS proceeding type
--
--   8. Cross-appeal family (4 rules)
--      RoP.237   (Cross-appeal 3mo, decision-flavor) → UPC_APP extension
--      RoP.238.1 (Reply to cross-appeal 2mo, decision-flavor) → UPC_APP extension
--      RoP.237   (Cross-appeal 15d, order-flavor) → UPC_APP_ORDERS
--      RoP.238.2 (Reply to cross-appeal 15d, order-flavor) → UPC_APP_ORDERS
--
--   9. Lay-open books / discovery (3 rules)
--      RoP.142.2 (Defence 2mo)
--      RoP.142.3 (Reply 14d)
--      RoP.142.3 (Rejoinder 14d)
--      → new UPC_DISCOVERY proceeding type
--
-- Design notes:
--   - The timeline model assumes a single trigger date with all deadlines
--     cascading from it. R.151 / R.221.1 / R.220.2 / R.220.3 / R.237 (15d) /
--     R.238.2 each have their own trigger anchor in the legal rule (cost
--     decision, leave-granted/refused, SoG-orders). To preserve that
--     semantic without breaking the single-trigger UI, these rules either
--     get their own proceeding type (UPC_COST_APPEAL with cost-decision as
--     trigger) or live in a tree with deadline_notes calling out the actual
--     legal anchor (UPC_APP_ORDERS).
--   - Damages and lay-open books are downstream sub-procedures with their
--     own application step as the trigger; new proceeding types are the
--     natural fit (UPC_DAMAGES, UPC_DISCOVERY).
--   - UPC_APP gains the 224.2(a) "decision-flavor" cross-appeal pair which
--     chains cleanly off the existing app.grounds rule.

-- ============================================================================
-- 1. Proceeding type rows
-- ============================================================================

INSERT INTO paliad.proceeding_types (code, name, name_en, description, jurisdiction, category, default_color, sort_order, is_active) VALUES
    ('UPC_DAMAGES',     'Schadensbemessungsverfahren',  'Damages Determination',           'UPC-Schadensbemessung (R.131.2 ff., R.137-139)',           'UPC', 'fristenrechner', '#3b82f6', 105, true),
    ('UPC_DISCOVERY',   'Bucheinsichtsverfahren',       'Lay-open Books / Discovery',      'UPC-Bucheinsicht / Rechnungslegung (R.141 ff., R.142)',    'UPC', 'fristenrechner', '#3b82f6', 106, true),
    ('UPC_COST_APPEAL', 'Berufung Kostenentscheidung',  'Cost-Decision Appeal',            'UPC-Berufungsverfahren gegen Kostenentscheidung (R.221.1)','UPC', 'fristenrechner', '#8b5cf6', 107, true),
    ('UPC_APP_ORDERS',  'Berufung Anordnungen',         'Order Appeal (15-day track)',     'UPC-Berufung gegen Anordnungen / Ermessensüberprüfung',    'UPC', 'fristenrechner', '#8b5cf6', 108, true)
ON CONFLICT (code) DO NOTHING;

-- ============================================================================
-- 2. Rule rows. Same shape as migration 012; same DO block pattern.
-- ============================================================================
DO $$
DECLARE
    v_upc_inf      int;
    v_upc_app      int;
    v_damages      int;
    v_discovery    int;
    v_cost_appeal  int;
    v_app_orders   int;

    -- Look-ups for parent_id chains (existing rules)
    r_inf_decision uuid;
    r_app_grounds  uuid;

    -- New rule UUIDs we need to reference for chaining
    r_damages_app    uuid;
    r_damages_def    uuid;
    r_damages_reply  uuid;

    r_disc_app       uuid;
    r_disc_def       uuid;
    r_disc_reply     uuid;

    r_cost_decision  uuid;

    r_app_ord_order  uuid;

    r_app_cross_a    uuid;
    r_app_ord_cross  uuid;
BEGIN
    SELECT id INTO v_upc_inf     FROM paliad.proceeding_types WHERE code = 'UPC_INF';
    SELECT id INTO v_upc_app     FROM paliad.proceeding_types WHERE code = 'UPC_APP';
    SELECT id INTO v_damages     FROM paliad.proceeding_types WHERE code = 'UPC_DAMAGES';
    SELECT id INTO v_discovery   FROM paliad.proceeding_types WHERE code = 'UPC_DISCOVERY';
    SELECT id INTO v_cost_appeal FROM paliad.proceeding_types WHERE code = 'UPC_COST_APPEAL';
    SELECT id INTO v_app_orders  FROM paliad.proceeding_types WHERE code = 'UPC_APP_ORDERS';

    SELECT id INTO r_inf_decision
      FROM paliad.deadline_rules
     WHERE proceeding_type_id = v_upc_inf AND code = 'inf.decision';

    SELECT id INTO r_app_grounds
      FROM paliad.deadline_rules
     WHERE proceeding_type_id = v_upc_app AND code = 'app.grounds';

    -- Idempotent: skip if we've already seeded the damages root.
    IF EXISTS (
        SELECT 1 FROM paliad.deadline_rules
         WHERE proceeding_type_id = v_damages AND code = 'damages.app'
    ) THEN
        RETURN;
    END IF;

    -- ========================================================================
    -- UPC_DAMAGES — 4 entries (1 root + 3 calculated rules ported)
    -- ========================================================================
    r_damages_app   := gen_random_uuid();
    r_damages_def   := gen_random_uuid();
    r_damages_reply := gen_random_uuid();

    INSERT INTO paliad.deadline_rules (id, proceeding_type_id, parent_id, code, name, name_en, primary_party, event_type, is_mandatory, duration_value, duration_unit, rule_code, deadline_notes, sequence_order, is_active) VALUES
        (r_damages_app,     v_damages, NULL,            'damages.app',     'Antrag auf Schadensbemessung', 'Application for Determination of Damages', 'claimant',  'filing',  true, 0, 'months', NULL,         NULL, 0, true),
        (r_damages_def,     v_damages, r_damages_app,   'damages.defence', 'Klageerwiderung',              'Defence to Application for Damages',       'defendant', 'filing',  true, 2, 'months', 'RoP.137.2',  NULL, 1, true),
        (r_damages_reply,   v_damages, r_damages_def,   'damages.reply',   'Replik',                       'Reply',                                    'claimant',  'filing',  true, 1, 'months', 'RoP.139',    NULL, 2, true),
        (gen_random_uuid(), v_damages, r_damages_reply, 'damages.rejoin',  'Duplik',                       'Rejoinder',                                'defendant', 'filing',  true, 1, 'months', 'RoP.139',    NULL, 3, true);

    -- ========================================================================
    -- UPC_DISCOVERY — 4 entries (1 root + 3 calculated rules ported)
    -- ========================================================================
    r_disc_app   := gen_random_uuid();
    r_disc_def   := gen_random_uuid();
    r_disc_reply := gen_random_uuid();

    INSERT INTO paliad.deadline_rules (id, proceeding_type_id, parent_id, code, name, name_en, primary_party, event_type, is_mandatory, duration_value, duration_unit, rule_code, deadline_notes, sequence_order, is_active) VALUES
        (r_disc_app,        v_discovery, NULL,         'disc.app',     'Antrag auf Bucheinsicht', 'Request to Lay Open Books', 'claimant',  'filing', true, 0, 'months', NULL,        NULL, 0, true),
        (r_disc_def,        v_discovery, r_disc_app,   'disc.defence', 'Klageerwiderung',         'Defence',                   'defendant', 'filing', true, 2, 'months', 'RoP.142.2', NULL, 1, true),
        (r_disc_reply,      v_discovery, r_disc_def,   'disc.reply',   'Replik',                  'Reply',                     'claimant',  'filing', true, 14, 'days',  'RoP.142.3', NULL, 2, true),
        (gen_random_uuid(), v_discovery, r_disc_reply, 'disc.rejoin',  'Duplik',                  'Rejoinder',                 'defendant', 'filing', true, 14, 'days',  'RoP.142.3', NULL, 3, true);

    -- ========================================================================
    -- UPC_INF extension — Antrag auf Kostenfestsetzung (R.151)
    -- 1 calculated rule ported. Chains off existing inf.decision.
    -- The inf.decision row is IsRootEvent (parent_id=NULL, duration=0) so its
    -- computed date equals the trigger date; inf.cost_app therefore renders at
    -- trigger + 1mo. The deadline_notes call out the actual legal anchor.
    -- ========================================================================
    INSERT INTO paliad.deadline_rules (id, proceeding_type_id, parent_id, code, name, name_en, primary_party, event_type, is_mandatory, duration_value, duration_unit, rule_code, deadline_notes, sequence_order, is_active) VALUES
        (gen_random_uuid(), v_upc_inf, r_inf_decision, 'inf.cost_app', 'Antrag auf Kostenentscheidung', 'Application for Cost Decision', 'both', 'filing', true, 1, 'months', 'RoP.151', 'Frist 1 Monat ab Zustellung der Hauptentscheidung', 7, true);

    -- ========================================================================
    -- UPC_COST_APPEAL — 2 entries (1 root + 1 ported rule)
    -- The user enters the cost-decision date as trigger; R.221.1 anchors on it.
    -- ========================================================================
    r_cost_decision := gen_random_uuid();

    INSERT INTO paliad.deadline_rules (id, proceeding_type_id, parent_id, code, name, name_en, primary_party, event_type, is_mandatory, duration_value, duration_unit, rule_code, deadline_notes, sequence_order, is_active) VALUES
        (r_cost_decision,   v_cost_appeal, NULL,            'cost.decision',  'Kostenfestsetzungsbeschluss', 'Cost Decision (Rule 157)',           'court', 'decision', true, 0, 'months', NULL,         NULL, 0, true),
        (gen_random_uuid(), v_cost_appeal, r_cost_decision, 'cost.leave_app', 'Antrag auf Berufungszulassung','Application for Leave to Appeal',    'both',  'filing',   true, 15, 'days',  'RoP.221.1',  'Frist 15 Tage ab Zustellung der Kostenentscheidung', 1, true);

    -- ========================================================================
    -- UPC_APP extension — decision-flavor cross-appeal pair
    -- 2 calculated rules ported. R.237 chains off app.grounds (which now
    -- correctly anchors on the appealed-decision date per migration 029).
    -- ========================================================================
    r_app_cross_a := gen_random_uuid();

    INSERT INTO paliad.deadline_rules (id, proceeding_type_id, parent_id, code, name, name_en, primary_party, event_type, is_mandatory, duration_value, duration_unit, rule_code, deadline_notes, sequence_order, is_active) VALUES
        (r_app_cross_a,     v_upc_app, r_app_grounds,  'app.cross_a',       'Anschlussberufung',              'Cross-Appeal',           'both', 'filing', false, 3, 'months', 'RoP.237',   'Frist 3 Monate ab Zustellung der Berufungsbegründung (R.224.2(a))', 5, true),
        (gen_random_uuid(), v_upc_app, r_app_cross_a,  'app.cross_a_reply', 'Erwiderung Anschlussberufung',   'Reply to Cross-Appeal',  'both', 'filing', false, 2, 'months', 'RoP.238.1', NULL, 6, true);

    -- ========================================================================
    -- UPC_APP_ORDERS — 5 entries (1 root + 4 ported rules)
    -- All 15-day deadlines. Trigger = the order/decision being appealed.
    -- R.220.2 / R.220.3 anchor directly on trigger. R.237 (order-flavor)
    -- chains as a parallel branch with deadline_notes calling out the
    -- legal anchor (Statement of Grounds R.224.2(b), itself 15d after order).
    -- ========================================================================
    r_app_ord_order := gen_random_uuid();
    r_app_ord_cross := gen_random_uuid();

    INSERT INTO paliad.deadline_rules (id, proceeding_type_id, parent_id, code, name, name_en, primary_party, event_type, is_mandatory, duration_value, duration_unit, rule_code, deadline_notes, sequence_order, is_active) VALUES
        (r_app_ord_order,   v_app_orders, NULL,            'app_ord.order',       'Anordnung / angegriffene Entscheidung', 'Order / Appealed Decision',         'court', 'decision', true,  0,  'months', NULL,        NULL, 0, true),
        (gen_random_uuid(), v_app_orders, r_app_ord_order, 'app_ord.with_leave',  'Berufung mit Zulassung',                'Appeal (Orders & with leave)',      'both',  'filing',   true,  15, 'days',   'RoP.220.2', 'Frist 15 Tage ab Zustellung der Anordnung bzw. der Zulassungsentscheidung', 1, true),
        (gen_random_uuid(), v_app_orders, r_app_ord_order, 'app_ord.discretion',  'Antrag auf Ermessensüberprüfung',       'Request for Discretionary Review',  'both',  'filing',   true,  15, 'days',   'RoP.220.3', 'Frist 15 Tage ab Zustellung der Entscheidung über die Versagung der Berufungszulassung', 2, true),
        (r_app_ord_cross,   v_app_orders, r_app_ord_order, 'app_ord.cross',       'Anschlussberufung',                     'Cross-Appeal',                      'both',  'filing',   false, 15, 'days',   'RoP.237',   'Frist 15 Tage ab Zustellung der Berufungsbegründung (R.224.2(b))', 3, true),
        (gen_random_uuid(), v_app_orders, r_app_ord_cross, 'app_ord.cross_reply', 'Erwiderung Anschlussberufung',          'Reply to Cross-Appeal',             'both',  'filing',   false, 15, 'days',   'RoP.238.2', 'Frist 15 Tage ab Zustellung der Anschlussberufung', 4, true);
END $$;
