-- Migration : architecture intervention complète (Teams + PCT + workflow)
--   - teams_channels (canaux Teams configurés)
--   - server_clusters (groupes avec ordre de redémarrage)
--   - contacts enrichis (teams_upn, phone, is_pct_member)
--   - applications enrichies (teams_channel_id, pct_required, pct_email override)
--   - servers enrichis (FK contacts, teams, pct, snap policy, hooks pre/post,
--                       cluster + cluster_order)
--   - patch_planning_import_rows enrichis (workflow intervention complet)
-- Idempotent — exécutable plusieurs fois.

-- ─── 1) Nouvelles tables ──────────────────────────────────────

CREATE TABLE IF NOT EXISTS public.teams_channels (
    id SERIAL PRIMARY KEY,
    name text NOT NULL,
    webhook_url text NOT NULL,
    description text,
    is_active boolean NOT NULL DEFAULT true,
    is_default boolean NOT NULL DEFAULT false,
    created_at timestamptz NOT NULL DEFAULT now()
);

CREATE TABLE IF NOT EXISTS public.server_clusters (
    id SERIAL PRIMARY KEY,
    name text NOT NULL UNIQUE,
    description text,
    reboot_strategy text NOT NULL DEFAULT 'sequential',
        -- sequential | parallel
    is_active boolean NOT NULL DEFAULT true,
    created_at timestamptz NOT NULL DEFAULT now()
);

-- ─── 2) Enrichir contacts ─────────────────────────────────────

ALTER TABLE public.contacts
    ADD COLUMN IF NOT EXISTS teams_upn     text,
    ADD COLUMN IF NOT EXISTS phone         text,
    ADD COLUMN IF NOT EXISTS is_pct_member boolean DEFAULT false;

-- ─── 3) Enrichir applications ────────────────────────────────

ALTER TABLE public.applications
    ADD COLUMN IF NOT EXISTS teams_channel_id integer REFERENCES public.teams_channels(id) ON DELETE SET NULL,
    ADD COLUMN IF NOT EXISTS pct_required     boolean DEFAULT false,
    ADD COLUMN IF NOT EXISTS pct_email        text;
    -- pct_email : override si différent du défaut global (pct.reims@sanef.com)

-- ─── 4) Enrichir servers ─────────────────────────────────────

ALTER TABLE public.servers
    ADD COLUMN IF NOT EXISTS responsable_domaine_contact_id integer REFERENCES public.contacts(id) ON DELETE SET NULL,
    ADD COLUMN IF NOT EXISTS referent_technique_contact_id integer REFERENCES public.contacts(id) ON DELETE SET NULL,
    ADD COLUMN IF NOT EXISTS valideur_ra_contact_id        integer REFERENCES public.contacts(id) ON DELETE SET NULL,
    ADD COLUMN IF NOT EXISTS teams_channel_id              integer REFERENCES public.teams_channels(id) ON DELETE SET NULL,
    ADD COLUMN IF NOT EXISTS pct_required                  boolean DEFAULT false,
    ADD COLUMN IF NOT EXISTS requires_snapshot             boolean DEFAULT true,
    ADD COLUMN IF NOT EXISTS snap_can_be_skipped           boolean DEFAULT false,
    ADD COLUMN IF NOT EXISTS pre_patch_cmd                 text,
    ADD COLUMN IF NOT EXISTS post_patch_cmd                text,
    ADD COLUMN IF NOT EXISTS cluster_id                    integer REFERENCES public.server_clusters(id) ON DELETE SET NULL,
    ADD COLUMN IF NOT EXISTS cluster_order                 integer;

-- Backfill : physiques → requires_snapshot=false (snap vCenter pas applicable)
UPDATE public.servers
   SET requires_snapshot = false
 WHERE LOWER(COALESCE(machine_type::text, '')) LIKE '%physic%';

-- ─── 5) Enrichir patch_planning_import_rows (workflow intervention) ─

ALTER TABLE public.patch_planning_import_rows
    ADD COLUMN IF NOT EXISTS intervention_started_at  timestamptz,
    ADD COLUMN IF NOT EXISTS intervention_finished_at timestamptz,
    ADD COLUMN IF NOT EXISTS validated_at             timestamptz,
    ADD COLUMN IF NOT EXISTS validated_by_contact_id  integer REFERENCES public.contacts(id) ON DELETE SET NULL,
    ADD COLUMN IF NOT EXISTS validation_status        text,
        -- 'ok' | 'ko' | 'en_attente' | NULL
    ADD COLUMN IF NOT EXISTS validation_note          text,
    ADD COLUMN IF NOT EXISTS snap_skipped             boolean DEFAULT false,
    ADD COLUMN IF NOT EXISTS snap_skip_reason         text,
    ADD COLUMN IF NOT EXISTS patch_forced             boolean DEFAULT false,
    ADD COLUMN IF NOT EXISTS patch_forced_reason      text,
    ADD COLUMN IF NOT EXISTS teams_reminder_sent_at   timestamptz,
    ADD COLUMN IF NOT EXISTS teams_start_sent_at      timestamptz,
    ADD COLUMN IF NOT EXISTS teams_end_sent_at        timestamptz,
    ADD COLUMN IF NOT EXISTS pct_mail_sent_at         timestamptz,
    ADD COLUMN IF NOT EXISTS rollback_done_at         timestamptz,
    ADD COLUMN IF NOT EXISTS rollback_method          text;
    -- rollback_method : 'yum_undo' | 'snapshot_restore' | 'commvault' | 'manual'

-- ─── 6) Index ─────────────────────────────────────────────────

CREATE INDEX IF NOT EXISTS idx_pp_rows_validation_status
    ON public.patch_planning_import_rows(validation_status)
    WHERE validation_status IS NOT NULL;

CREATE INDEX IF NOT EXISTS idx_pp_rows_intervention_started
    ON public.patch_planning_import_rows(intervention_started_at)
    WHERE intervention_started_at IS NOT NULL;

CREATE INDEX IF NOT EXISTS idx_servers_cluster
    ON public.servers(cluster_id, cluster_order)
    WHERE cluster_id IS NOT NULL;

CREATE INDEX IF NOT EXISTS idx_servers_resp_domaine
    ON public.servers(responsable_domaine_contact_id)
    WHERE responsable_domaine_contact_id IS NOT NULL;

CREATE INDEX IF NOT EXISTS idx_servers_referent
    ON public.servers(referent_technique_contact_id)
    WHERE referent_technique_contact_id IS NOT NULL;

CREATE INDEX IF NOT EXISTS idx_servers_valideur
    ON public.servers(valideur_ra_contact_id)
    WHERE valideur_ra_contact_id IS NOT NULL;

-- ─── 7) GRANT pour le user applicatif ─────────────────────────

GRANT SELECT, INSERT, UPDATE, DELETE ON public.teams_channels  TO patchcenter;
GRANT SELECT, INSERT, UPDATE, DELETE ON public.server_clusters TO patchcenter;
GRANT USAGE, SELECT ON SEQUENCE public.teams_channels_id_seq   TO patchcenter;
GRANT USAGE, SELECT ON SEQUENCE public.server_clusters_id_seq  TO patchcenter;

-- ─── Note ─────────────────────────────────────────────────────
-- Le mail PCT global ('pct.reims@sanef.com') sera configuré via l'UI
-- Settings (M5) car app_secrets utilise un chiffrement Fernet — on ne peut
-- pas l'INSERT en clair via SQL.
