-- Migration 037: IT Glue sync tables (all prefixed itg_)
-- Full backup of IT Glue data synced from the API

-- ─── Reference / Lookup Tables ───────────────────────────────────────────────

CREATE TABLE IF NOT EXISTS itg_organization_types (
  id                BIGINT PRIMARY KEY,
  name              TEXT NOT NULL,
  created_at        TIMESTAMPTZ,
  updated_at        TIMESTAMPTZ,
  synced_at         TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS itg_organization_statuses (
  id                BIGINT PRIMARY KEY,
  name              TEXT NOT NULL,
  created_at        TIMESTAMPTZ,
  updated_at        TIMESTAMPTZ,
  synced_at         TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS itg_configuration_types (
  id                BIGINT PRIMARY KEY,
  name              TEXT NOT NULL,
  created_at        TIMESTAMPTZ,
  updated_at        TIMESTAMPTZ,
  synced_at         TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS itg_configuration_statuses (
  id                BIGINT PRIMARY KEY,
  name              TEXT NOT NULL,
  created_at        TIMESTAMPTZ,
  updated_at        TIMESTAMPTZ,
  synced_at         TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS itg_contact_types (
  id                BIGINT PRIMARY KEY,
  name              TEXT NOT NULL,
  created_at        TIMESTAMPTZ,
  updated_at        TIMESTAMPTZ,
  synced_at         TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS itg_password_categories (
  id                BIGINT PRIMARY KEY,
  name              TEXT NOT NULL,
  created_at        TIMESTAMPTZ,
  updated_at        TIMESTAMPTZ,
  synced_at         TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS itg_manufacturers (
  id                BIGINT PRIMARY KEY,
  name              TEXT NOT NULL,
  created_at        TIMESTAMPTZ,
  updated_at        TIMESTAMPTZ,
  synced_at         TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS itg_models (
  id                BIGINT PRIMARY KEY,
  manufacturer_id   BIGINT,
  name              TEXT NOT NULL,
  created_at        TIMESTAMPTZ,
  updated_at        TIMESTAMPTZ,
  synced_at         TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS itg_operating_systems (
  id                BIGINT PRIMARY KEY,
  name              TEXT NOT NULL,
  created_at        TIMESTAMPTZ,
  updated_at        TIMESTAMPTZ,
  synced_at         TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS itg_platforms (
  id                BIGINT PRIMARY KEY,
  name              TEXT NOT NULL,
  created_at        TIMESTAMPTZ,
  updated_at        TIMESTAMPTZ,
  synced_at         TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS itg_countries (
  id                BIGINT PRIMARY KEY,
  name              TEXT NOT NULL,
  iso_code          TEXT,
  created_at        TIMESTAMPTZ,
  updated_at        TIMESTAMPTZ,
  synced_at         TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ─── Organizations ────────────────────────────────────────────────────────────

CREATE TABLE IF NOT EXISTS itg_organizations (
  id                        BIGINT PRIMARY KEY,
  name                      TEXT NOT NULL,
  short_name                TEXT,
  organization_type_id      BIGINT,
  organization_type_name    TEXT,
  organization_status_id    BIGINT,
  organization_status_name  TEXT,
  psa_integration           TEXT,
  psa_id                    TEXT,
  sync_active               BOOLEAN DEFAULT FALSE,
  primary_org               BOOLEAN DEFAULT FALSE,
  quick_notes               TEXT,
  description               TEXT,
  alert                     TEXT,
  parent_id                 BIGINT,
  created_at                TIMESTAMPTZ,
  updated_at                TIMESTAMPTZ,
  synced_at                 TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_itg_organizations_name ON itg_organizations(name);
CREATE INDEX IF NOT EXISTS idx_itg_organizations_type ON itg_organizations(organization_type_id);
CREATE INDEX IF NOT EXISTS idx_itg_organizations_status ON itg_organizations(organization_status_id);
CREATE INDEX IF NOT EXISTS idx_itg_organizations_updated ON itg_organizations(updated_at);

-- ─── Locations ────────────────────────────────────────────────────────────────

CREATE TABLE IF NOT EXISTS itg_locations (
  id                BIGINT PRIMARY KEY,
  organization_id   BIGINT NOT NULL,
  organization_name TEXT,
  name              TEXT NOT NULL,
  primary_location  BOOLEAN DEFAULT FALSE,
  address_1         TEXT,
  address_2         TEXT,
  city              TEXT,
  region_name       TEXT,
  postal_code       TEXT,
  country_name      TEXT,
  phone             TEXT,
  fax               TEXT,
  notes             TEXT,
  created_at        TIMESTAMPTZ,
  updated_at        TIMESTAMPTZ,
  synced_at         TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_itg_locations_org ON itg_locations(organization_id);

-- ─── Contacts ─────────────────────────────────────────────────────────────────

CREATE TABLE IF NOT EXISTS itg_contacts (
  id                  BIGINT PRIMARY KEY,
  organization_id     BIGINT NOT NULL,
  organization_name   TEXT,
  first_name          TEXT,
  last_name           TEXT,
  name                TEXT,
  title               TEXT,
  contact_type_id     BIGINT,
  contact_type_name   TEXT,
  location_id         BIGINT,
  important           BOOLEAN DEFAULT FALSE,
  notes               TEXT,
  emails              JSONB DEFAULT '[]',
  phones              JSONB DEFAULT '[]',
  created_at          TIMESTAMPTZ,
  updated_at          TIMESTAMPTZ,
  synced_at           TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_itg_contacts_org ON itg_contacts(organization_id);
CREATE INDEX IF NOT EXISTS idx_itg_contacts_name ON itg_contacts(last_name, first_name);

-- ─── Configurations ───────────────────────────────────────────────────────────

CREATE TABLE IF NOT EXISTS itg_configurations (
  id                          BIGINT PRIMARY KEY,
  organization_id             BIGINT NOT NULL,
  organization_name           TEXT,
  name                        TEXT NOT NULL,
  hostname                    TEXT,
  primary_ip                  TEXT,
  mac_address                 TEXT,
  serial_number               TEXT,
  asset_tag                   TEXT,
  position                    TEXT,
  installed_by                TEXT,
  purchased_by                TEXT,
  notes                       TEXT,
  operating_system_notes      TEXT,
  warranty_expires_at         TIMESTAMPTZ,
  installed_at                TIMESTAMPTZ,
  purchased_at                TIMESTAMPTZ,
  end_of_life_at              TIMESTAMPTZ,
  configuration_type_id       BIGINT,
  configuration_type_name     TEXT,
  configuration_status_id     BIGINT,
  configuration_status_name   TEXT,
  manufacturer_id             BIGINT,
  manufacturer_name           TEXT,
  model_id                    BIGINT,
  model_name                  TEXT,
  operating_system_id         BIGINT,
  operating_system_name       TEXT,
  location_id                 BIGINT,
  contact_id                  BIGINT,
  rmm_id                      TEXT,
  rmm_integration_type        TEXT,
  created_at                  TIMESTAMPTZ,
  updated_at                  TIMESTAMPTZ,
  synced_at                   TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_itg_configurations_org ON itg_configurations(organization_id);
CREATE INDEX IF NOT EXISTS idx_itg_configurations_hostname ON itg_configurations(hostname);
CREATE INDEX IF NOT EXISTS idx_itg_configurations_serial ON itg_configurations(serial_number);
CREATE INDEX IF NOT EXISTS idx_itg_configurations_name ON itg_configurations(name);
CREATE INDEX IF NOT EXISTS idx_itg_configurations_rmm ON itg_configurations(rmm_id);

-- ─── Configuration Interfaces ─────────────────────────────────────────────────

CREATE TABLE IF NOT EXISTS itg_configuration_interfaces (
  id                  BIGINT PRIMARY KEY,
  configuration_id    BIGINT NOT NULL,
  organization_id     BIGINT,
  name                TEXT,
  ip_address          TEXT,
  mac_address         TEXT,
  primary_interface   BOOLEAN DEFAULT FALSE,
  notes               TEXT,
  created_at          TIMESTAMPTZ,
  updated_at          TIMESTAMPTZ,
  synced_at           TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_itg_config_interfaces_config ON itg_configuration_interfaces(configuration_id);

-- ─── Flexible Asset Types ─────────────────────────────────────────────────────

CREATE TABLE IF NOT EXISTS itg_flexible_asset_types (
  id            BIGINT PRIMARY KEY,
  name          TEXT NOT NULL,
  description   TEXT,
  icon          TEXT,
  enabled       BOOLEAN DEFAULT TRUE,
  builtin       BOOLEAN DEFAULT FALSE,
  created_at    TIMESTAMPTZ,
  updated_at    TIMESTAMPTZ,
  synced_at     TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ─── Flexible Asset Fields ────────────────────────────────────────────────────

CREATE TABLE IF NOT EXISTS itg_flexible_asset_fields (
  id                        BIGINT PRIMARY KEY,
  flexible_asset_type_id    BIGINT NOT NULL,
  name                      TEXT NOT NULL,
  kind                      TEXT,
  hint                      TEXT,
  decimals                  INT DEFAULT 0,
  tag_type                  TEXT,
  required                  BOOLEAN DEFAULT FALSE,
  use_for_title             BOOLEAN DEFAULT FALSE,
  expiration                BOOLEAN DEFAULT FALSE,
  show_in_list              BOOLEAN DEFAULT FALSE,
  created_at                TIMESTAMPTZ,
  updated_at                TIMESTAMPTZ,
  synced_at                 TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_itg_fa_fields_type ON itg_flexible_asset_fields(flexible_asset_type_id);

-- ─── Flexible Assets ──────────────────────────────────────────────────────────

CREATE TABLE IF NOT EXISTS itg_flexible_assets (
  id                        BIGINT PRIMARY KEY,
  organization_id           BIGINT NOT NULL,
  organization_name         TEXT,
  flexible_asset_type_id    BIGINT NOT NULL,
  flexible_asset_type_name  TEXT,
  name                      TEXT,
  traits                    JSONB DEFAULT '{}',
  archived                  BOOLEAN DEFAULT FALSE,
  created_at                TIMESTAMPTZ,
  updated_at                TIMESTAMPTZ,
  synced_at                 TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_itg_flexible_assets_org ON itg_flexible_assets(organization_id);
CREATE INDEX IF NOT EXISTS idx_itg_flexible_assets_type ON itg_flexible_assets(flexible_asset_type_id);
CREATE INDEX IF NOT EXISTS idx_itg_flexible_assets_name ON itg_flexible_assets(name);
CREATE INDEX IF NOT EXISTS idx_itg_flexible_assets_updated ON itg_flexible_assets(updated_at);

-- ─── Password Folders ─────────────────────────────────────────────────────────

CREATE TABLE IF NOT EXISTS itg_password_folders (
  id                BIGINT PRIMARY KEY,
  organization_id   BIGINT NOT NULL,
  organization_name TEXT,
  name              TEXT NOT NULL,
  inherited         BOOLEAN DEFAULT FALSE,
  created_at        TIMESTAMPTZ,
  updated_at        TIMESTAMPTZ,
  synced_at         TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_itg_password_folders_org ON itg_password_folders(organization_id);

-- ─── Passwords ────────────────────────────────────────────────────────────────

CREATE TABLE IF NOT EXISTS itg_passwords (
  id                      BIGINT PRIMARY KEY,
  organization_id         BIGINT NOT NULL,
  organization_name       TEXT,
  name                    TEXT NOT NULL,
  username                TEXT,
  password                TEXT,
  url                     TEXT,
  notes                   TEXT,
  password_category_id    BIGINT,
  password_category_name  TEXT,
  password_folder_id      BIGINT,
  autofill_selectors      TEXT,
  otp_enabled             BOOLEAN DEFAULT FALSE,
  archived                BOOLEAN DEFAULT FALSE,
  created_at              TIMESTAMPTZ,
  updated_at              TIMESTAMPTZ,
  synced_at               TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_itg_passwords_org ON itg_passwords(organization_id);
CREATE INDEX IF NOT EXISTS idx_itg_passwords_name ON itg_passwords(name);

-- ─── Documents ────────────────────────────────────────────────────────────────

CREATE TABLE IF NOT EXISTS itg_documents (
  id                BIGINT PRIMARY KEY,
  organization_id   BIGINT NOT NULL,
  organization_name TEXT,
  name              TEXT NOT NULL,
  content           TEXT,
  draft             BOOLEAN DEFAULT FALSE,
  archived          BOOLEAN DEFAULT FALSE,
  created_at        TIMESTAMPTZ,
  updated_at        TIMESTAMPTZ,
  synced_at         TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_itg_documents_org ON itg_documents(organization_id);

-- ─── Domains ──────────────────────────────────────────────────────────────────

CREATE TABLE IF NOT EXISTS itg_domains (
  id                BIGINT PRIMARY KEY,
  organization_id   BIGINT NOT NULL,
  organization_name TEXT,
  name              TEXT NOT NULL,
  screenshot        TEXT,
  whois_updated_at  TIMESTAMPTZ,
  expires_at        TIMESTAMPTZ,
  registrar_name    TEXT,
  notes             TEXT,
  created_at        TIMESTAMPTZ,
  updated_at        TIMESTAMPTZ,
  synced_at         TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_itg_domains_org ON itg_domains(organization_id);
CREATE INDEX IF NOT EXISTS idx_itg_domains_name ON itg_domains(name);
CREATE INDEX IF NOT EXISTS idx_itg_domains_expires ON itg_domains(expires_at);

-- ─── Expirations ──────────────────────────────────────────────────────────────

CREATE TABLE IF NOT EXISTS itg_expirations (
  id                      BIGINT PRIMARY KEY,
  organization_id         BIGINT NOT NULL,
  organization_name       TEXT,
  resource_id             BIGINT,
  resource_type           TEXT,
  resource_name           TEXT,
  expiration_type         TEXT,
  description             TEXT,
  expiration_date         TIMESTAMPTZ,
  notify                  BOOLEAN DEFAULT FALSE,
  created_at              TIMESTAMPTZ,
  updated_at              TIMESTAMPTZ,
  synced_at               TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_itg_expirations_org ON itg_expirations(organization_id);
CREATE INDEX IF NOT EXISTS idx_itg_expirations_date ON itg_expirations(expiration_date);

-- ─── Sync History ─────────────────────────────────────────────────────────────

CREATE TABLE IF NOT EXISTS itg_sync_history (
  id              SERIAL PRIMARY KEY,
  sync_type       TEXT NOT NULL DEFAULT 'full',
  status          TEXT NOT NULL,
  triggered_by    TEXT DEFAULT 'system',
  started_at      TIMESTAMPTZ NOT NULL,
  completed_at    TIMESTAMPTZ,
  duration_ms     INTEGER,
  entities        JSONB DEFAULT '[]',
  error           TEXT,
  total_upserted  INTEGER DEFAULT 0
);

CREATE INDEX IF NOT EXISTS idx_itg_sync_history_started ON itg_sync_history(started_at DESC);
