-- Phase C: migrate Fristenrechner's in-memory rule tree into paliad.deadline_rules.
--
-- The Paliad public Fristenrechner UI exposes 9 simple proceeding types
-- (UPC_INF/UPC_REV/UPC_PI/UPC_APP/DE_INF/DE_NULL/EPA_OPP/EPA_APP/EP_GRANT)
-- with bilingual names. These sit alongside the richer KanzlAI-ported types
-- (INF/REV/CCR/APM/APP/AMD/ZPO_CIVIL) used for matter-attached Fristen.
--
-- Rules ported verbatim from the pre-Phase-C internal/calc/deadline_rules.go
-- so /tools/fristenrechner results remain byte-identical after the swap.
-- Codes intentionally reuse the old string values (e.g. "inf.soc") even
-- though some collide with KanzlAI rule codes — proceeding_type_id
-- disambiguates, and the client renders by name/nameEN, not code.

ALTER TABLE paliad.proceeding_types
    ADD COLUMN IF NOT EXISTS name_en text NOT NULL DEFAULT '';
ALTER TABLE paliad.deadline_rules
    ADD COLUMN IF NOT EXISTS name_en text NOT NULL DEFAULT '';

-- Backfill name_en for existing KanzlAI-ported entries.
UPDATE paliad.proceeding_types SET name_en = name WHERE name_en = '';
UPDATE paliad.deadline_rules   SET name_en = name WHERE name_en = '';

-- ============================================================================
-- UI-facing proceeding types. Name/NameEN copied verbatim from the old
-- in-memory ProceedingType structs.
-- ============================================================================
INSERT INTO paliad.proceeding_types (code, name, name_en, description, jurisdiction, category, default_color, sort_order, is_active) VALUES
    ('UPC_INF',  'Verletzungsverfahren',          'Infringement Action',              'UPC-Verletzungsklage',       'UPC', 'fristenrechner', '#3b82f6', 101, true),
    ('UPC_REV',  'Nichtigkeitsklage',             'Revocation Action',                'UPC-Nichtigkeitsklage',      'UPC', 'fristenrechner', '#ef4444', 102, true),
    ('UPC_PI',   'Einstweilige Maßnahmen',        'Provisional Measures',             'UPC-Einstweilige Maßnahmen', 'UPC', 'fristenrechner', '#f59e0b', 103, true),
    ('UPC_APP',  'Berufung',                      'Appeal',                           'UPC-Berufung',               'UPC', 'fristenrechner', '#8b5cf6', 104, true),
    ('DE_INF',   'Verletzungsklage (LG)',         'Infringement (Regional Court)',    'Deutsche Verletzungsklage',  'DE',  'fristenrechner', '#6366f1', 201, true),
    ('DE_NULL',  'Nichtigkeitsverfahren (BPatG)', 'Nullity (Federal Patent Court)',   'Deutsche Nichtigkeitsklage', 'DE',  'fristenrechner', '#6366f1', 202, true),
    ('EPA_OPP',  'Einspruchsverfahren',           'Opposition Proceedings',           'EPA-Einspruchsverfahren',    'EPA', 'fristenrechner', '#059669', 301, true),
    ('EPA_APP',  'Beschwerdeverfahren',           'Appeal Proceedings',               'EPA-Beschwerdeverfahren',    'EPA', 'fristenrechner', '#059669', 302, true),
    ('EP_GRANT', 'EP-Erteilungsverfahren',        'EP Grant Procedure',               'EP-Erteilungsverfahren',     'EPA', 'fristenrechner', '#059669', 303, true)
ON CONFLICT (code) DO NOTHING;

-- ============================================================================
-- Rules — every field ported 1:1 from deadline_rules.go. Parent codes follow
-- the original RelativeTo chains. Zero-duration rules with NULL parent_id
-- render as IsRootEvent (due = trigger date); zero-duration rules with a
-- parent render as IsCourtSet (empty due date). This matches the old
-- in-memory classification.
-- ============================================================================
DO $$
DECLARE
    v_upc_inf  int; v_upc_rev  int; v_upc_pi   int; v_upc_app  int;
    v_de_inf   int; v_de_null  int;
    v_epa_opp  int; v_epa_app  int; v_ep_grant int;

    -- UPC_INF
    r_inf_soc     uuid; r_inf_sod     uuid;
    r_inf_reply   uuid; r_inf_rejoin  uuid;

    -- UPC_REV
    r_rev_app     uuid; r_rev_defence uuid;
    r_rev_reply   uuid; r_rev_rejoin  uuid;

    -- UPC_PI
    r_pi_app      uuid;

    -- UPC_APP
    r_app_notice  uuid; r_app_grounds uuid;

    -- DE_INF
    r_de_inf_klage    uuid; r_de_inf_berufung uuid;

    -- DE_NULL
    r_de_null_klage   uuid; r_de_null_berufung uuid;

    -- EPA_OPP
    r_epa_opp_grant      uuid; r_epa_opp_frist      uuid;
    r_epa_opp_beschwerde uuid;

    -- EPA_APP
    r_epa_app_entsch uuid;

    -- EP_GRANT
    r_ep_grant_filing  uuid; r_ep_grant_publish uuid;
BEGIN
    SELECT id INTO v_upc_inf  FROM paliad.proceeding_types WHERE code = 'UPC_INF';
    SELECT id INTO v_upc_rev  FROM paliad.proceeding_types WHERE code = 'UPC_REV';
    SELECT id INTO v_upc_pi   FROM paliad.proceeding_types WHERE code = 'UPC_PI';
    SELECT id INTO v_upc_app  FROM paliad.proceeding_types WHERE code = 'UPC_APP';
    SELECT id INTO v_de_inf   FROM paliad.proceeding_types WHERE code = 'DE_INF';
    SELECT id INTO v_de_null  FROM paliad.proceeding_types WHERE code = 'DE_NULL';
    SELECT id INTO v_epa_opp  FROM paliad.proceeding_types WHERE code = 'EPA_OPP';
    SELECT id INTO v_epa_app  FROM paliad.proceeding_types WHERE code = 'EPA_APP';
    SELECT id INTO v_ep_grant FROM paliad.proceeding_types WHERE code = 'EP_GRANT';

    -- Idempotent: skip if we've already seeded.
    IF EXISTS (
        SELECT 1 FROM paliad.deadline_rules
         WHERE proceeding_type_id = v_upc_inf AND code = 'inf.soc'
    ) THEN
        RETURN;
    END IF;

    -- ========================================================================
    -- UPC_INF — 7 rules
    -- ========================================================================
    r_inf_soc    := gen_random_uuid();
    r_inf_sod    := gen_random_uuid();
    r_inf_reply  := gen_random_uuid();
    r_inf_rejoin := 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_inf_soc,         v_upc_inf, NULL,         'inf.soc',      'Klageerhebung',         'Statement of Claim',  'claimant',  'filing',  true, 0, 'months', NULL,       NULL,                         0, true),
        (r_inf_sod,         v_upc_inf, r_inf_soc,    'inf.sod',      'Klageerwiderung',       'Statement of Defence','defendant', 'filing',  true, 3, 'months', 'RoP 23',   NULL,                         1, true),
        (r_inf_reply,       v_upc_inf, r_inf_sod,    'inf.reply',    'Replik',                'Reply to Defence',    'claimant',  'filing',  true, 2, 'months', 'RoP 29b',  NULL,                         2, true),
        (r_inf_rejoin,      v_upc_inf, r_inf_reply,  'inf.rejoin',   'Duplik',                'Rejoinder',           'defendant', 'filing',  true, 1, 'months', 'RoP 29c',  NULL,                         3, true),
        (gen_random_uuid(), v_upc_inf, NULL,         'inf.interim',  'Zwischenverfahren',     'Interim Conference',  'court',     'hearing', true, 0, 'months', NULL,       'Termin vom Gericht bestimmt',4, true),
        (gen_random_uuid(), v_upc_inf, NULL,         'inf.oral',     'Mündliche Verhandlung', 'Oral Hearing',        'court',     'hearing', true, 0, 'months', NULL,       NULL,                         5, true),
        (gen_random_uuid(), v_upc_inf, NULL,         'inf.decision', 'Entscheidung',          'Decision',            'court',     'decision',true, 0, 'months', NULL,       NULL,                         6, true);

    -- ========================================================================
    -- UPC_REV — 7 rules
    -- ========================================================================
    r_rev_app     := gen_random_uuid();
    r_rev_defence := gen_random_uuid();
    r_rev_reply   := gen_random_uuid();
    r_rev_rejoin  := 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_rev_app,         v_upc_rev, NULL,          'rev.app',      'Nichtigkeitsklage',     'Application for Revocation', 'claimant',  'filing',  true, 0, 'months', NULL, NULL, 0, true),
        (r_rev_defence,     v_upc_rev, r_rev_app,     'rev.defence',  'Klageerwiderung',       'Defence to Revocation',      'defendant', 'filing',  true, 3, 'months', NULL, NULL, 1, true),
        (r_rev_reply,       v_upc_rev, r_rev_defence, 'rev.reply',    'Replik',                'Reply',                      'claimant',  'filing',  true, 2, 'months', NULL, NULL, 2, true),
        (r_rev_rejoin,      v_upc_rev, r_rev_reply,   'rev.rejoin',   'Duplik',                'Rejoinder',                  'defendant', 'filing',  true, 2, 'months', NULL, NULL, 3, true),
        (gen_random_uuid(), v_upc_rev, NULL,          'rev.interim',  'Zwischenverfahren',     'Interim Conference',         'court',     'hearing', true, 0, 'months', NULL, NULL, 4, true),
        (gen_random_uuid(), v_upc_rev, NULL,          'rev.oral',     'Mündliche Verhandlung', 'Oral Hearing',               'court',     'hearing', true, 0, 'months', NULL, NULL, 5, true),
        (gen_random_uuid(), v_upc_rev, NULL,          'rev.decision', 'Entscheidung',          'Decision',                   'court',     'decision',true, 0, 'months', NULL, NULL, 6, true);

    -- ========================================================================
    -- UPC_PI — 4 rules
    -- ========================================================================
    r_pi_app := 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_pi_app,          v_upc_pi, NULL, 'pi.app',      'Antrag',                'Application',  'claimant', 'filing',  true, 0, 'months', NULL, NULL,                         0, true),
        (gen_random_uuid(), v_upc_pi, NULL, 'pi.response', 'Erwiderung',            'Response',     'defendant','filing',  true, 0, 'months', NULL, 'Frist vom Gericht bestimmt', 1, true),
        (gen_random_uuid(), v_upc_pi, NULL, 'pi.oral',     'Mündliche Verhandlung', 'Oral Hearing', 'court',    'hearing', true, 0, 'months', NULL, NULL,                         2, true),
        (gen_random_uuid(), v_upc_pi, NULL, 'pi.order',    'Beschluss',             'Order',        'court',    'decision',true, 0, 'months', NULL, NULL,                         3, true);

    -- ========================================================================
    -- UPC_APP — 5 rules
    -- ========================================================================
    r_app_notice  := gen_random_uuid();
    r_app_grounds := 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_notice,      v_upc_app, NULL,          'app.notice',   'Berufungseinlegung',   'Notice of Appeal',     'both',  'filing',  true, 2, 'months', 'RoP 220.1', NULL, 0, true),
        (r_app_grounds,     v_upc_app, r_app_notice,  'app.grounds',  'Berufungsbegründung',  'Statement of Grounds', 'both',  'filing',  true, 2, 'months', 'RoP 220.1', NULL, 1, true),
        (gen_random_uuid(), v_upc_app, r_app_grounds, 'app.response', 'Berufungserwiderung',  'Response to Appeal',   'both',  'filing',  true, 2, 'months', NULL,        NULL, 2, true),
        (gen_random_uuid(), v_upc_app, NULL,          'app.oral',     'Mündliche Verhandlung','Oral Hearing',         'court', 'hearing', true, 0, 'months', NULL,        NULL, 3, true),
        (gen_random_uuid(), v_upc_app, NULL,          'app.decision', 'Entscheidung',         'Decision',             'court', 'decision',true, 0, 'months', NULL,        NULL, 4, true);

    -- ========================================================================
    -- DE_INF — 8 rules
    -- ========================================================================
    r_de_inf_klage    := gen_random_uuid();
    r_de_inf_berufung := 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_de_inf_klage,    v_de_inf, NULL,              'de_inf.klage',      'Klageerhebung',       'Filing of Action',    'claimant',  'filing',  true,  0, 'months', NULL,        NULL,                                  0, true),
        (gen_random_uuid(), v_de_inf, r_de_inf_klage,    'de_inf.erwidg',     'Klageerwiderung',     'Statement of Defence','defendant', 'filing',  true,  6, 'weeks',  '§ 276 ZPO', 'Regelfrist, kann verlängert werden',  1, true),
        (gen_random_uuid(), v_de_inf, NULL,              'de_inf.replik',     'Replik',              'Reply',               'claimant',  'filing',  false, 4, 'weeks',  NULL,        'Frist vom Gericht bestimmt',          2, true),
        (gen_random_uuid(), v_de_inf, NULL,              'de_inf.duplik',     'Duplik',              'Rejoinder',           'defendant', 'filing',  false, 4, 'weeks',  NULL,        'Frist vom Gericht bestimmt',          3, true),
        (gen_random_uuid(), v_de_inf, NULL,              'de_inf.termin',     'Haupttermin',         'Main Hearing',        'court',     'hearing', true,  0, 'months', NULL,        NULL,                                  4, true),
        (gen_random_uuid(), v_de_inf, NULL,              'de_inf.urteil',     'Urteil',              'Judgment',            'court',     'decision',true,  0, 'months', NULL,        NULL,                                  5, true),
        (r_de_inf_berufung, v_de_inf, NULL,              'de_inf.berufung',   'Berufungsfrist',      'Appeal Period',       'both',      'filing',  true,  1, 'months', '§ 517 ZPO', 'Ab Zustellung des Urteils',           6, true),
        (gen_random_uuid(), v_de_inf, r_de_inf_berufung, 'de_inf.beruf_begr', 'Berufungsbegründung', 'Appeal Statement',    'both',      'filing',  true,  2, 'months', '§ 520 ZPO', NULL,                                  7, true);

    -- ========================================================================
    -- DE_NULL — 6 rules
    -- ========================================================================
    r_de_null_klage    := gen_random_uuid();
    r_de_null_berufung := 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_de_null_klage,    v_de_null, NULL,               'de_null.klage',      'Nichtigkeitsklage',     'Nullity Action',    'claimant',  'filing',  true, 0, 'months', NULL,        NULL,                         0, true),
        (gen_random_uuid(),  v_de_null, r_de_null_klage,    'de_null.erwidg',     'Klageerwiderung',       'Defence',           'defendant', 'filing',  true, 2, 'months', '§ 82 PatG', NULL,                         1, true),
        (gen_random_uuid(),  v_de_null, NULL,               'de_null.termin',     'Mündliche Verhandlung', 'Oral Hearing',      'court',     'hearing', true, 0, 'months', NULL,        NULL,                         2, true),
        (gen_random_uuid(),  v_de_null, NULL,               'de_null.urteil',     'Urteil',                'Judgment',          'court',     'decision',true, 0, 'months', NULL,        NULL,                         3, true),
        (r_de_null_berufung, v_de_null, NULL,               'de_null.berufung',   'Berufungsfrist',        'Appeal Period',     'both',      'filing',  true, 1, 'months', '§ 110 PatG','Ab Zustellung des Urteils',  4, true),
        (gen_random_uuid(),  v_de_null, r_de_null_berufung, 'de_null.beruf_begr', 'Berufungsbegründung',   'Appeal Statement',  'both',      'filing',  true, 1, 'months', '§ 111 PatG',NULL,                         5, true);

    -- ========================================================================
    -- EPA_OPP — 6 rules
    -- ========================================================================
    r_epa_opp_grant      := gen_random_uuid();
    r_epa_opp_frist      := gen_random_uuid();
    r_epa_opp_beschwerde := 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_epa_opp_grant,      v_epa_opp, NULL,                 'epa_opp.grant',           'Veröffentlichung der Erteilung','Publication of Grant',  'court',     'decision',true, 0, 'months', NULL,           NULL,                              0, true),
        (r_epa_opp_frist,      v_epa_opp, r_epa_opp_grant,      'epa_opp.frist',           'Einspruchsfrist',               'Opposition Period',     'both',      'filing',  true, 9, 'months', 'Art. 99 EPÜ', NULL,                              1, true),
        (gen_random_uuid(),    v_epa_opp, r_epa_opp_frist,      'epa_opp.erwidg',          'Erwiderung des Patentinhabers', 'Proprietor''s Response','defendant', 'filing',  true, 4, 'months', 'R. 79(1) EPÜ',NULL,                              2, true),
        (gen_random_uuid(),    v_epa_opp, NULL,                 'epa_opp.entsch',          'Entscheidung',                  'Decision',              'court',     'decision',true, 0, 'months', NULL,           NULL,                              3, true),
        (r_epa_opp_beschwerde, v_epa_opp, NULL,                 'epa_opp.beschwerde',      'Beschwerdefrist',               'Appeal Period',         'both',      'filing',  true, 2, 'months', 'Art. 108 EPÜ','Ab Zustellung der Entscheidung',  4, true),
        (gen_random_uuid(),    v_epa_opp, r_epa_opp_beschwerde, 'epa_opp.beschwerde_begr', 'Beschwerdebegründung',          'Statement of Grounds',  'both',      'filing',  true, 4, 'months', 'Art. 108 EPÜ',NULL,                              5, true);

    -- ========================================================================
    -- EPA_APP — 6 rules
    -- ========================================================================
    r_epa_app_entsch := 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_epa_app_entsch,  v_epa_app, NULL,             'epa_app.entsch',     'Zustellung der Entscheidung', 'Notification of Decision','court',    'decision',true,  0, 'months', NULL,           NULL,                                         0, true),
        (gen_random_uuid(), v_epa_app, r_epa_app_entsch, 'epa_app.beschwerde', 'Beschwerdeeinlegung',         'Filing of Appeal',        'both',     'filing',  true,  2, 'months', 'Art. 108 EPÜ', NULL,                                         1, true),
        (gen_random_uuid(), v_epa_app, r_epa_app_entsch, 'epa_app.begr',       'Beschwerdebegründung',        'Statement of Grounds',    'both',     'filing',  true,  4, 'months', 'Art. 108 EPÜ', 'Ab Zustellung, nicht ab Beschwerdeeinlegung',2, true),
        (gen_random_uuid(), v_epa_app, NULL,             'epa_app.erwidg',     'Erwiderung',                  'Response',                'both',     'filing',  false, 0, 'months', NULL,           'Frist von der Beschwerdekammer bestimmt',    3, true),
        (gen_random_uuid(), v_epa_app, NULL,             'epa_app.oral',       'Mündliche Verhandlung',       'Oral Proceedings',        'court',    'hearing', false, 0, 'months', NULL,           NULL,                                         4, true),
        (gen_random_uuid(), v_epa_app, NULL,             'epa_app.entsch2',    'Entscheidung',                'Decision',                'court',    'decision',true,  0, 'months', NULL,           NULL,                                         5, true);

    -- ========================================================================
    -- EP_GRANT — 7 rules
    -- ========================================================================
    r_ep_grant_filing  := gen_random_uuid();
    r_ep_grant_publish := 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_ep_grant_filing,  v_ep_grant, NULL,               'ep_grant.filing',   'Anmeldung',                'Filing',                        'claimant', 'filing',  true,  0, 'months', NULL,           NULL,                            0, true),
        (gen_random_uuid(),  v_ep_grant, r_ep_grant_filing,  'ep_grant.search',   'Recherchenbericht',        'Search Report',                 'court',    'decision',true,  6, 'months', NULL,           'Richtwert, kann länger dauern', 1, true),
        (r_ep_grant_publish, v_ep_grant, r_ep_grant_filing,  'ep_grant.publish',  'Veröffentlichung (A1)',    'Publication (A1)',              'court',    'decision',true, 18, 'months', 'Art. 93 EPÜ',  'Ab Prioritätstag',              2, true),
        (gen_random_uuid(),  v_ep_grant, r_ep_grant_publish, 'ep_grant.exam_req', 'Prüfungsantrag',           'Request for Examination',       'claimant', 'filing',  true,  6, 'months', 'R. 70(1) EPÜ', 'Ab Hinweis auf Möglichkeit',    3, true),
        (gen_random_uuid(),  v_ep_grant, NULL,               'ep_grant.r71_3',    'Mitteilung nach R. 71(3)', 'Communication under R. 71(3)',  'court',    'decision',true,  0, 'months', 'R. 71(3) EPÜ', NULL,                            4, true),
        (gen_random_uuid(),  v_ep_grant, NULL,               'ep_grant.approval', 'Zustimmung + Übersetzung', 'Approval + Translation',        'claimant', 'filing',  true,  4, 'months', 'R. 71(3) EPÜ', 'Erteilungs- und Druckgebühr',   5, true),
        (gen_random_uuid(),  v_ep_grant, NULL,               'ep_grant.grant',    'Erteilung (B1)',           'Grant (B1)',                    'court',    'decision',true,  0, 'months', NULL,           NULL,                            6, true);
END $$;
