-- Dispo import staging foundation
-- Run: psql $DATABASE_URL -f packages/db/prisma/migrations/20260314_dispo_import_staging.sql

DO $$
BEGIN
  CREATE TYPE "ImportBatchStatus" AS ENUM (
    'DRAFT',
    'STAGING',
    'STAGED',
    'REVIEW_READY',
    'APPROVED',
    'COMMITTING',
    'COMMITTED',
    'FAILED',
    'CANCELLED'
  );
EXCEPTION
  WHEN duplicate_object THEN NULL;
END $$;

DO $$
BEGIN
  CREATE TYPE "StagedRecordStatus" AS ENUM (
    'PARSED',
    'NORMALIZED',
    'UNRESOLVED',
    'APPROVED',
    'REJECTED',
    'COMMITTED',
    'FAILED'
  );
EXCEPTION
  WHEN duplicate_object THEN NULL;
END $$;

DO $$
BEGIN
  CREATE TYPE "DispoImportSourceKind" AS ENUM (
    'REFERENCE',
    'PLANNING',
    'CHARGEABILITY'
  );
EXCEPTION
  WHEN duplicate_object THEN NULL;
END $$;

DO $$
BEGIN
  CREATE TYPE "DispoStagedRecordType" AS ENUM (
    'RESOURCE',
    'CLIENT',
    'PROJECT',
    'ASSIGNMENT',
    'VACATION',
    'AVAILABILITY_RULE',
    'UNRESOLVED'
  );
EXCEPTION
  WHEN duplicate_object THEN NULL;
END $$;

CREATE TABLE IF NOT EXISTS import_batches (
  id text PRIMARY KEY,
  "sourceSystem" text NOT NULL DEFAULT 'DISPO_V2',
  status "ImportBatchStatus" NOT NULL DEFAULT 'DRAFT',
  "referenceSourceFile" text,
  "planningSourceFile" text,
  "chargeabilitySourceFile" text,
  notes text,
  summary jsonb NOT NULL DEFAULT '{}'::jsonb,
  "startedAt" timestamptz,
  "stagedAt" timestamptz,
  "approvedAt" timestamptz,
  "committedAt" timestamptz,
  "failedAt" timestamptz,
  "createdAt" timestamptz NOT NULL DEFAULT now(),
  "updatedAt" timestamptz NOT NULL DEFAULT now()
);

CREATE TABLE IF NOT EXISTS staged_resources (
  id text PRIMARY KEY,
  "importBatchId" text NOT NULL REFERENCES import_batches(id) ON DELETE CASCADE,
  status "StagedRecordStatus" NOT NULL DEFAULT 'PARSED',
  "sourceKind" "DispoImportSourceKind" NOT NULL,
  "sourceWorkbook" text NOT NULL,
  "sourceSheet" text NOT NULL,
  "sourceRow" integer NOT NULL,
  "sourceColumn" text,
  "canonicalExternalId" text NOT NULL,
  "enterpriseId" text,
  eid text,
  "displayName" text,
  email text,
  chapter text,
  "chapterCode" text,
  "managementLevelGroupName" text,
  "managementLevelName" text,
  "countryCode" text,
  "metroCityName" text,
  "clientUnitName" text,
  "resourceType" "ResourceType",
  "chargeabilityTarget" double precision,
  fte double precision,
  availability jsonb,
  "roleTokens" text[] NOT NULL DEFAULT ARRAY[]::text[],
  warnings text[] NOT NULL DEFAULT ARRAY[]::text[],
  "errorMessage" text,
  "rawPayload" jsonb NOT NULL,
  "normalizedData" jsonb NOT NULL DEFAULT '{}'::jsonb,
  "createdAt" timestamptz NOT NULL DEFAULT now(),
  "updatedAt" timestamptz NOT NULL DEFAULT now()
);

CREATE TABLE IF NOT EXISTS staged_clients (
  id text PRIMARY KEY,
  "importBatchId" text NOT NULL REFERENCES import_batches(id) ON DELETE CASCADE,
  status "StagedRecordStatus" NOT NULL DEFAULT 'PARSED',
  "sourceKind" "DispoImportSourceKind" NOT NULL,
  "sourceWorkbook" text NOT NULL,
  "sourceSheet" text NOT NULL,
  "sourceRow" integer NOT NULL,
  "sourceColumn" text,
  "clientCode" text,
  "parentClientCode" text,
  name text NOT NULL,
  "sortOrder" integer,
  "isActive" boolean NOT NULL DEFAULT true,
  warnings text[] NOT NULL DEFAULT ARRAY[]::text[],
  "errorMessage" text,
  "rawPayload" jsonb NOT NULL,
  "normalizedData" jsonb NOT NULL DEFAULT '{}'::jsonb,
  "createdAt" timestamptz NOT NULL DEFAULT now(),
  "updatedAt" timestamptz NOT NULL DEFAULT now()
);

CREATE TABLE IF NOT EXISTS staged_projects (
  id text PRIMARY KEY,
  "importBatchId" text NOT NULL REFERENCES import_batches(id) ON DELETE CASCADE,
  status "StagedRecordStatus" NOT NULL DEFAULT 'PARSED',
  "sourceKind" "DispoImportSourceKind" NOT NULL,
  "sourceWorkbook" text NOT NULL,
  "sourceSheet" text NOT NULL,
  "sourceRow" integer NOT NULL,
  "sourceColumn" text,
  "projectKey" text NOT NULL,
  "shortCode" text,
  name text,
  "clientCode" text,
  "utilizationCategoryCode" text,
  "orderType" "OrderType",
  "allocationType" "AllocationType",
  "winProbability" integer,
  "isInternal" boolean NOT NULL DEFAULT false,
  "isTbd" boolean NOT NULL DEFAULT false,
  "startDate" date,
  "endDate" date,
  warnings text[] NOT NULL DEFAULT ARRAY[]::text[],
  "errorMessage" text,
  "rawPayload" jsonb NOT NULL,
  "normalizedData" jsonb NOT NULL DEFAULT '{}'::jsonb,
  "createdAt" timestamptz NOT NULL DEFAULT now(),
  "updatedAt" timestamptz NOT NULL DEFAULT now()
);

CREATE TABLE IF NOT EXISTS staged_assignments (
  id text PRIMARY KEY,
  "importBatchId" text NOT NULL REFERENCES import_batches(id) ON DELETE CASCADE,
  status "StagedRecordStatus" NOT NULL DEFAULT 'PARSED',
  "sourceKind" "DispoImportSourceKind" NOT NULL,
  "sourceWorkbook" text NOT NULL,
  "sourceSheet" text NOT NULL,
  "sourceRow" integer NOT NULL,
  "sourceColumn" text,
  "resourceExternalId" text NOT NULL,
  "projectKey" text,
  "assignmentDate" date,
  "startDate" date,
  "endDate" date,
  "hoursPerDay" double precision,
  percentage double precision,
  "slotFraction" double precision,
  "roleToken" text,
  "roleName" text,
  "chapterToken" text,
  "utilizationCategoryCode" text,
  "winProbability" integer,
  "isInternal" boolean NOT NULL DEFAULT false,
  "isUnassigned" boolean NOT NULL DEFAULT false,
  "isTbd" boolean NOT NULL DEFAULT false,
  warnings text[] NOT NULL DEFAULT ARRAY[]::text[],
  "errorMessage" text,
  "rawPayload" jsonb NOT NULL,
  "normalizedData" jsonb NOT NULL DEFAULT '{}'::jsonb,
  "createdAt" timestamptz NOT NULL DEFAULT now(),
  "updatedAt" timestamptz NOT NULL DEFAULT now()
);

CREATE TABLE IF NOT EXISTS staged_vacations (
  id text PRIMARY KEY,
  "importBatchId" text NOT NULL REFERENCES import_batches(id) ON DELETE CASCADE,
  status "StagedRecordStatus" NOT NULL DEFAULT 'PARSED',
  "sourceKind" "DispoImportSourceKind" NOT NULL,
  "sourceWorkbook" text NOT NULL,
  "sourceSheet" text NOT NULL,
  "sourceRow" integer NOT NULL,
  "sourceColumn" text,
  "resourceExternalId" text NOT NULL,
  "vacationType" "VacationType" NOT NULL,
  "startDate" date NOT NULL,
  "endDate" date NOT NULL,
  note text,
  "holidayName" text,
  "isHalfDay" boolean NOT NULL DEFAULT false,
  "halfDayPart" text,
  "isPublicHoliday" boolean NOT NULL DEFAULT false,
  warnings text[] NOT NULL DEFAULT ARRAY[]::text[],
  "errorMessage" text,
  "rawPayload" jsonb NOT NULL,
  "normalizedData" jsonb NOT NULL DEFAULT '{}'::jsonb,
  "createdAt" timestamptz NOT NULL DEFAULT now(),
  "updatedAt" timestamptz NOT NULL DEFAULT now()
);

CREATE TABLE IF NOT EXISTS staged_availability_rules (
  id text PRIMARY KEY,
  "importBatchId" text NOT NULL REFERENCES import_batches(id) ON DELETE CASCADE,
  status "StagedRecordStatus" NOT NULL DEFAULT 'PARSED',
  "sourceKind" "DispoImportSourceKind" NOT NULL,
  "sourceWorkbook" text NOT NULL,
  "sourceSheet" text NOT NULL,
  "sourceRow" integer NOT NULL,
  "sourceColumn" text,
  "resourceExternalId" text NOT NULL,
  "ruleType" text NOT NULL,
  weekday integer,
  "effectiveStartDate" date,
  "effectiveEndDate" date,
  "availableHours" double precision,
  percentage double precision,
  "isResolved" boolean NOT NULL DEFAULT false,
  warnings text[] NOT NULL DEFAULT ARRAY[]::text[],
  "errorMessage" text,
  "rawPayload" jsonb NOT NULL,
  "normalizedData" jsonb NOT NULL DEFAULT '{}'::jsonb,
  "createdAt" timestamptz NOT NULL DEFAULT now(),
  "updatedAt" timestamptz NOT NULL DEFAULT now()
);

CREATE TABLE IF NOT EXISTS staged_unresolved_records (
  id text PRIMARY KEY,
  "importBatchId" text NOT NULL REFERENCES import_batches(id) ON DELETE CASCADE,
  status "StagedRecordStatus" NOT NULL DEFAULT 'UNRESOLVED',
  "sourceKind" "DispoImportSourceKind" NOT NULL,
  "sourceWorkbook" text NOT NULL,
  "sourceSheet" text NOT NULL,
  "sourceRow" integer NOT NULL,
  "sourceColumn" text,
  "recordType" "DispoStagedRecordType" NOT NULL,
  "resourceExternalId" text,
  "projectKey" text,
  message text NOT NULL,
  "resolutionHint" text,
  warnings text[] NOT NULL DEFAULT ARRAY[]::text[],
  "rawPayload" jsonb NOT NULL,
  "normalizedData" jsonb NOT NULL DEFAULT '{}'::jsonb,
  "createdAt" timestamptz NOT NULL DEFAULT now(),
  "updatedAt" timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_import_batches_status
  ON import_batches (status);

CREATE INDEX IF NOT EXISTS idx_staged_resources_batch_status
  ON staged_resources ("importBatchId", status);

CREATE INDEX IF NOT EXISTS idx_staged_resources_canonical_external_id
  ON staged_resources ("canonicalExternalId");

CREATE INDEX IF NOT EXISTS idx_staged_clients_batch_status
  ON staged_clients ("importBatchId", status);

CREATE INDEX IF NOT EXISTS idx_staged_clients_client_code
  ON staged_clients ("clientCode");

CREATE INDEX IF NOT EXISTS idx_staged_projects_batch_status
  ON staged_projects ("importBatchId", status);

CREATE INDEX IF NOT EXISTS idx_staged_projects_project_key
  ON staged_projects ("projectKey");

CREATE INDEX IF NOT EXISTS idx_staged_assignments_batch_status
  ON staged_assignments ("importBatchId", status);

CREATE INDEX IF NOT EXISTS idx_staged_assignments_resource_external_id
  ON staged_assignments ("resourceExternalId");

CREATE INDEX IF NOT EXISTS idx_staged_assignments_project_key
  ON staged_assignments ("projectKey");

CREATE INDEX IF NOT EXISTS idx_staged_assignments_assignment_date
  ON staged_assignments ("assignmentDate");

CREATE INDEX IF NOT EXISTS idx_staged_vacations_batch_status
  ON staged_vacations ("importBatchId", status);

CREATE INDEX IF NOT EXISTS idx_staged_vacations_resource_external_id
  ON staged_vacations ("resourceExternalId");

CREATE INDEX IF NOT EXISTS idx_staged_vacations_start_end
  ON staged_vacations ("startDate", "endDate");

CREATE INDEX IF NOT EXISTS idx_staged_availability_rules_batch_status
  ON staged_availability_rules ("importBatchId", status);

CREATE INDEX IF NOT EXISTS idx_staged_availability_rules_resource_external_id
  ON staged_availability_rules ("resourceExternalId");

CREATE INDEX IF NOT EXISTS idx_staged_unresolved_records_batch_status
  ON staged_unresolved_records ("importBatchId", status);

CREATE INDEX IF NOT EXISTS idx_staged_unresolved_records_record_type
  ON staged_unresolved_records ("recordType");

CREATE INDEX IF NOT EXISTS idx_staged_unresolved_records_resource_external_id
  ON staged_unresolved_records ("resourceExternalId");

CREATE INDEX IF NOT EXISTS idx_staged_unresolved_records_project_key
  ON staged_unresolved_records ("projectKey");
