CREATE TABLE IF NOT EXISTS categories (
  id VARCHAR(36) NOT NULL,
  source_type VARCHAR(32) NOT NULL DEFAULT 'third_party',
  api_account_id VARCHAR(36) NULL DEFAULT 'env-biedawo',
  provider VARCHAR(64) NULL DEFAULT 'biedawo',
  external_id VARCHAR(160) NULL,
  remote_category_id VARCHAR(120) NULL,
  name VARCHAR(160) NOT NULL,
  sort_order INT NOT NULL DEFAULT 0,
  enabled TINYINT NOT NULL DEFAULT 1,
  raw_payload JSON NULL,
  last_synced_at DATETIME NULL,
  created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
  updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS courses (
  id VARCHAR(36) NOT NULL,
  source_type VARCHAR(32) NOT NULL DEFAULT 'third_party',
  api_account_id VARCHAR(36) NULL DEFAULT 'env-biedawo',
  provider VARCHAR(64) NULL DEFAULT 'biedawo',
  external_id VARCHAR(160) NULL,
  category_id VARCHAR(36) NULL,
  remote_category_id VARCHAR(120) NULL,
  remote_course_id VARCHAR(160) NULL,
  name VARCHAR(255) NOT NULL,
  price DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  content TEXT NULL,
  is_favorite TINYINT NOT NULL DEFAULT 0,
  enabled TINYINT NOT NULL DEFAULT 1,
  raw_payload JSON NULL,
  last_synced_at DATETIME NULL,
  created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
  updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

SET @categories_source_type_exists := (
  SELECT COUNT(*) FROM information_schema.columns
  WHERE table_schema = DATABASE() AND table_name = 'categories' AND column_name = 'source_type'
);
SET @categories_source_type_sql := IF(
  @categories_source_type_exists = 0,
  'ALTER TABLE categories ADD COLUMN source_type VARCHAR(32) NOT NULL DEFAULT ''third_party'' AFTER id',
  'SELECT 1'
);
PREPARE categories_source_type_stmt FROM @categories_source_type_sql;
EXECUTE categories_source_type_stmt;
DEALLOCATE PREPARE categories_source_type_stmt;

SET @categories_api_account_id_exists := (
  SELECT COUNT(*) FROM information_schema.columns
  WHERE table_schema = DATABASE() AND table_name = 'categories' AND column_name = 'api_account_id'
);
SET @categories_api_account_id_sql := IF(
  @categories_api_account_id_exists = 0,
  'ALTER TABLE categories ADD COLUMN api_account_id VARCHAR(36) NULL DEFAULT ''env-biedawo'' AFTER source_type',
  'SELECT 1'
);
PREPARE categories_api_account_id_stmt FROM @categories_api_account_id_sql;
EXECUTE categories_api_account_id_stmt;
DEALLOCATE PREPARE categories_api_account_id_stmt;

SET @categories_provider_exists := (
  SELECT COUNT(*) FROM information_schema.columns
  WHERE table_schema = DATABASE() AND table_name = 'categories' AND column_name = 'provider'
);
SET @categories_provider_sql := IF(
  @categories_provider_exists = 0,
  'ALTER TABLE categories ADD COLUMN provider VARCHAR(64) NULL DEFAULT ''biedawo'' AFTER source_type',
  'SELECT 1'
);
PREPARE categories_provider_stmt FROM @categories_provider_sql;
EXECUTE categories_provider_stmt;
DEALLOCATE PREPARE categories_provider_stmt;

SET @categories_external_id_exists := (
  SELECT COUNT(*) FROM information_schema.columns
  WHERE table_schema = DATABASE() AND table_name = 'categories' AND column_name = 'external_id'
);
SET @categories_external_id_sql := IF(
  @categories_external_id_exists = 0,
  'ALTER TABLE categories ADD COLUMN external_id VARCHAR(160) NULL AFTER provider',
  'SELECT 1'
);
PREPARE categories_external_id_stmt FROM @categories_external_id_sql;
EXECUTE categories_external_id_stmt;
DEALLOCATE PREPARE categories_external_id_stmt;

SET @categories_enabled_exists := (
  SELECT COUNT(*) FROM information_schema.columns
  WHERE table_schema = DATABASE() AND table_name = 'categories' AND column_name = 'enabled'
);
SET @categories_enabled_sql := IF(
  @categories_enabled_exists = 0,
  'ALTER TABLE categories ADD COLUMN enabled TINYINT NOT NULL DEFAULT 1 AFTER sort_order',
  'SELECT 1'
);
PREPARE categories_enabled_stmt FROM @categories_enabled_sql;
EXECUTE categories_enabled_stmt;
DEALLOCATE PREPARE categories_enabled_stmt;

SET @categories_last_synced_nullable := (
  SELECT COUNT(*) FROM information_schema.columns
  WHERE table_schema = DATABASE()
    AND table_name = 'categories'
    AND column_name = 'last_synced_at'
    AND is_nullable = 'NO'
);
SET @categories_last_synced_sql := IF(
  @categories_last_synced_nullable > 0,
  'ALTER TABLE categories MODIFY COLUMN last_synced_at DATETIME NULL',
  'SELECT 1'
);
PREPARE categories_last_synced_stmt FROM @categories_last_synced_sql;
EXECUTE categories_last_synced_stmt;
DEALLOCATE PREPARE categories_last_synced_stmt;

UPDATE categories
SET source_type = COALESCE(NULLIF(source_type, ''), 'third_party'),
    provider = COALESCE(NULLIF(provider, ''), 'biedawo'),
    external_id = COALESCE(NULLIF(external_id, ''), remote_category_id)
WHERE source_type IS NULL
   OR provider IS NULL
   OR external_id IS NULL
   OR source_type = ''
   OR provider = ''
   OR external_id = '';

SET @courses_source_type_exists := (
  SELECT COUNT(*) FROM information_schema.columns
  WHERE table_schema = DATABASE() AND table_name = 'courses' AND column_name = 'source_type'
);
SET @courses_source_type_sql := IF(
  @courses_source_type_exists = 0,
  'ALTER TABLE courses ADD COLUMN source_type VARCHAR(32) NOT NULL DEFAULT ''third_party'' AFTER id',
  'SELECT 1'
);
PREPARE courses_source_type_stmt FROM @courses_source_type_sql;
EXECUTE courses_source_type_stmt;
DEALLOCATE PREPARE courses_source_type_stmt;

SET @courses_api_account_id_exists := (
  SELECT COUNT(*) FROM information_schema.columns
  WHERE table_schema = DATABASE() AND table_name = 'courses' AND column_name = 'api_account_id'
);
SET @courses_api_account_id_sql := IF(
  @courses_api_account_id_exists = 0,
  'ALTER TABLE courses ADD COLUMN api_account_id VARCHAR(36) NULL DEFAULT ''env-biedawo'' AFTER source_type',
  'SELECT 1'
);
PREPARE courses_api_account_id_stmt FROM @courses_api_account_id_sql;
EXECUTE courses_api_account_id_stmt;
DEALLOCATE PREPARE courses_api_account_id_stmt;

SET @courses_provider_exists := (
  SELECT COUNT(*) FROM information_schema.columns
  WHERE table_schema = DATABASE() AND table_name = 'courses' AND column_name = 'provider'
);
SET @courses_provider_sql := IF(
  @courses_provider_exists = 0,
  'ALTER TABLE courses ADD COLUMN provider VARCHAR(64) NULL DEFAULT ''biedawo'' AFTER source_type',
  'SELECT 1'
);
PREPARE courses_provider_stmt FROM @courses_provider_sql;
EXECUTE courses_provider_stmt;
DEALLOCATE PREPARE courses_provider_stmt;

SET @courses_external_id_exists := (
  SELECT COUNT(*) FROM information_schema.columns
  WHERE table_schema = DATABASE() AND table_name = 'courses' AND column_name = 'external_id'
);
SET @courses_external_id_sql := IF(
  @courses_external_id_exists = 0,
  'ALTER TABLE courses ADD COLUMN external_id VARCHAR(160) NULL AFTER provider',
  'SELECT 1'
);
PREPARE courses_external_id_stmt FROM @courses_external_id_sql;
EXECUTE courses_external_id_stmt;
DEALLOCATE PREPARE courses_external_id_stmt;

SET @courses_price_exists := (
  SELECT COUNT(*) FROM information_schema.columns
  WHERE table_schema = DATABASE() AND table_name = 'courses' AND column_name = 'price'
);
SET @courses_price_sql := IF(
  @courses_price_exists = 0,
  'ALTER TABLE courses ADD COLUMN price DECIMAL(10,2) NOT NULL DEFAULT 0.00 AFTER name',
  'SELECT 1'
);
PREPARE courses_price_stmt FROM @courses_price_sql;
EXECUTE courses_price_stmt;
DEALLOCATE PREPARE courses_price_stmt;

SET @courses_content_exists := (
  SELECT COUNT(*) FROM information_schema.columns
  WHERE table_schema = DATABASE() AND table_name = 'courses' AND column_name = 'content'
);
SET @courses_content_sql := IF(
  @courses_content_exists = 0,
  'ALTER TABLE courses ADD COLUMN content TEXT NULL AFTER price',
  'SELECT 1'
);
PREPARE courses_content_stmt FROM @courses_content_sql;
EXECUTE courses_content_stmt;
DEALLOCATE PREPARE courses_content_stmt;

SET @courses_raw_payload_exists := (
  SELECT COUNT(*) FROM information_schema.columns
  WHERE table_schema = DATABASE() AND table_name = 'courses' AND column_name = 'raw_payload'
);
SET @courses_raw_payload_sql := IF(
  @courses_raw_payload_exists = 0,
  'ALTER TABLE courses ADD COLUMN raw_payload JSON NULL AFTER enabled',
  'SELECT 1'
);
PREPARE courses_raw_payload_stmt FROM @courses_raw_payload_sql;
EXECUTE courses_raw_payload_stmt;
DEALLOCATE PREPARE courses_raw_payload_stmt;

SET @courses_last_synced_nullable := (
  SELECT COUNT(*) FROM information_schema.columns
  WHERE table_schema = DATABASE()
    AND table_name = 'courses'
    AND column_name = 'last_synced_at'
    AND is_nullable = 'NO'
);
SET @courses_last_synced_sql := IF(
  @courses_last_synced_nullable > 0,
  'ALTER TABLE courses MODIFY COLUMN last_synced_at DATETIME NULL',
  'SELECT 1'
);
PREPARE courses_last_synced_stmt FROM @courses_last_synced_sql;
EXECUTE courses_last_synced_stmt;
DEALLOCATE PREPARE courses_last_synced_stmt;

UPDATE courses
SET source_type = COALESCE(NULLIF(source_type, ''), 'third_party'),
    provider = COALESCE(NULLIF(provider, ''), 'biedawo'),
    external_id = COALESCE(NULLIF(external_id, ''), remote_course_id)
WHERE source_type IS NULL
   OR provider IS NULL
   OR external_id IS NULL
   OR source_type = ''
   OR provider = ''
   OR external_id = '';

SET @categories_source_provider_external_index_exists := (
  SELECT COUNT(*) FROM information_schema.statistics
  WHERE table_schema = DATABASE()
    AND table_name = 'categories'
    AND index_name = 'idx_categories_source_provider_external'
);
SET @categories_source_provider_external_index_sql := IF(
  @categories_source_provider_external_index_exists = 0,
  'CREATE INDEX idx_categories_source_provider_external ON categories (source_type, provider, external_id)',
  'SELECT 1'
);
PREPARE categories_source_provider_external_index_stmt FROM @categories_source_provider_external_index_sql;
EXECUTE categories_source_provider_external_index_stmt;
DEALLOCATE PREPARE categories_source_provider_external_index_stmt;

SET @categories_provider_remote_index_exists := (
  SELECT COUNT(*) FROM information_schema.statistics
  WHERE table_schema = DATABASE()
    AND table_name = 'categories'
    AND index_name = 'idx_categories_provider_remote'
);
SET @categories_provider_remote_index_sql := IF(
  @categories_provider_remote_index_exists = 0,
  'CREATE INDEX idx_categories_provider_remote ON categories (provider, remote_category_id)',
  'SELECT 1'
);
PREPARE categories_provider_remote_index_stmt FROM @categories_provider_remote_index_sql;
EXECUTE categories_provider_remote_index_stmt;
DEALLOCATE PREPARE categories_provider_remote_index_stmt;

SET @courses_source_provider_external_category_index_exists := (
  SELECT COUNT(*) FROM information_schema.statistics
  WHERE table_schema = DATABASE()
    AND table_name = 'courses'
    AND index_name = 'idx_courses_source_provider_external_category'
);
SET @courses_source_provider_external_category_index_sql := IF(
  @courses_source_provider_external_category_index_exists = 0,
  'CREATE INDEX idx_courses_source_provider_external_category ON courses (source_type, provider, external_id, remote_category_id)',
  'SELECT 1'
);
PREPARE courses_source_provider_external_category_index_stmt FROM @courses_source_provider_external_category_index_sql;
EXECUTE courses_source_provider_external_category_index_stmt;
DEALLOCATE PREPARE courses_source_provider_external_category_index_stmt;

SET @courses_provider_category_updated_index_exists := (
  SELECT COUNT(*) FROM information_schema.statistics
  WHERE table_schema = DATABASE()
    AND table_name = 'courses'
    AND index_name = 'idx_courses_provider_category_updated'
);
SET @courses_provider_category_updated_index_sql := IF(
  @courses_provider_category_updated_index_exists = 0,
  'CREATE INDEX idx_courses_provider_category_updated ON courses (provider, remote_category_id, updated_at)',
  'SELECT 1'
);
PREPARE courses_provider_category_updated_index_stmt FROM @courses_provider_category_updated_index_sql;
EXECUTE courses_provider_category_updated_index_stmt;
DEALLOCATE PREPARE courses_provider_category_updated_index_stmt;
