package queries

import "database/sql"

func EnsureProductSeriesAutoInfraTables(pg *sql.DB) error {
	stmts := []string{
		`
CREATE TABLE IF NOT EXISTS mk_product_series_rule (
  id          BIGSERIAL PRIMARY KEY,
  series_id   BIGINT NOT NULL REFERENCES dfgrp(id) ON DELETE CASCADE,
  size_group  TEXT NOT NULL DEFAULT '',
  size_code   TEXT NOT NULL,
  ratio_qty   INTEGER NOT NULL DEFAULT 1,
  priority    INTEGER NOT NULL DEFAULT 0,
  is_active   BOOLEAN NOT NULL DEFAULT TRUE,
  source      TEXT NOT NULL DEFAULT 'manual',
  notes       TEXT NOT NULL DEFAULT '',
  created_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
  CONSTRAINT ck_mk_product_series_rule_ratio CHECK (ratio_qty > 0),
  CONSTRAINT uq_mk_product_series_rule UNIQUE (series_id, size_group, size_code)
)`,
		`CREATE INDEX IF NOT EXISTS ix_mk_product_series_rule_series ON mk_product_series_rule (series_id, is_active)`,
		`CREATE INDEX IF NOT EXISTS ix_mk_product_series_rule_group ON mk_product_series_rule (size_group, size_code)`,
		`
CREATE TABLE IF NOT EXISTS mk_product_series_stock_state (
  row_key       TEXT PRIMARY KEY,
  product_code  TEXT NOT NULL,
  color_code    TEXT NOT NULL,
  dim3_code     TEXT NOT NULL DEFAULT '',
  stock_hash    TEXT NOT NULL DEFAULT '',
  total_qty     NUMERIC(18,2) NOT NULL DEFAULT 0,
  last_seen_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at    TIMESTAMPTZ NOT NULL DEFAULT now()
)`,
		`CREATE INDEX IF NOT EXISTS ix_mk_product_series_stock_state_product ON mk_product_series_stock_state (product_code, updated_at DESC)`,
		`
CREATE TABLE IF NOT EXISTS mk_product_series_recalc_queue (
  id            BIGSERIAL PRIMARY KEY,
  row_key       TEXT NOT NULL,
  product_code  TEXT NOT NULL,
  color_code    TEXT NOT NULL,
  dim3_code     TEXT NOT NULL DEFAULT '',
  reason        TEXT NOT NULL DEFAULT '',
  status        TEXT NOT NULL DEFAULT 'pending',
  attempts      SMALLINT NOT NULL DEFAULT 0,
  available_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
  queued_at     TIMESTAMPTZ NOT NULL DEFAULT now(),
  processed_at  TIMESTAMPTZ,
  last_error    TEXT NOT NULL DEFAULT '',
  created_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
  CONSTRAINT ck_mk_product_series_recalc_queue_status CHECK (status IN ('pending','processing','done','failed'))
)`,
		`CREATE INDEX IF NOT EXISTS ix_mk_product_series_recalc_queue_status ON mk_product_series_recalc_queue (status, available_at, queued_at)`,
		`CREATE UNIQUE INDEX IF NOT EXISTS uq_mk_product_series_recalc_queue_pending ON mk_product_series_recalc_queue (row_key) WHERE status IN ('pending','processing')`,
		`
CREATE TABLE IF NOT EXISTS mk_product_series_job_log (
  id             BIGSERIAL PRIMARY KEY,
  job_name       TEXT NOT NULL,
  reason         TEXT NOT NULL DEFAULT '',
  started_at     TIMESTAMPTZ NOT NULL DEFAULT now(),
  finished_at    TIMESTAMPTZ,
  status         TEXT NOT NULL DEFAULT 'running',
  scanned_rows   INTEGER NOT NULL DEFAULT 0,
  changed_rows   INTEGER NOT NULL DEFAULT 0,
  processed_rows INTEGER NOT NULL DEFAULT 0,
  written_rows   INTEGER NOT NULL DEFAULT 0,
  skipped_rows   INTEGER NOT NULL DEFAULT 0,
  error_text     TEXT NOT NULL DEFAULT ''
)`,
		`CREATE INDEX IF NOT EXISTS ix_mk_product_series_job_log_started ON mk_product_series_job_log (started_at DESC)`,
		`
CREATE TABLE IF NOT EXISTS mk_product_series_apply_state (
  row_key          TEXT PRIMARY KEY,
  last_apply_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
  last_apply_kind  TEXT NOT NULL DEFAULT '',
  last_series_ids  TEXT NOT NULL DEFAULT '',
  updated_at       TIMESTAMPTZ NOT NULL DEFAULT now(),
  CONSTRAINT ck_mk_product_series_apply_state_kind CHECK (last_apply_kind IN ('', 'rules', 'fallback'))
)`,
		`CREATE INDEX IF NOT EXISTS ix_mk_product_series_apply_state_updated ON mk_product_series_apply_state (updated_at DESC)`,
		// Backward compatible schema upgrades.
		`ALTER TABLE mk_product_series_apply_state ADD COLUMN IF NOT EXISTS invalid_streak INTEGER NOT NULL DEFAULT 0`,
		`ALTER TABLE mk_product_series_apply_state ADD COLUMN IF NOT EXISTS last_invalid_at TIMESTAMPTZ`,
	}
	for _, stmt := range stmts {
		if _, err := pg.Exec(stmt); err != nil {
			return err
		}
	}

	// Ensure a default fallback series exists for "stok var ama seri secilemedi" cases.
	// The scheduler may apply it when no other rule matches. We create only the definition;
	// we intentionally do NOT auto-seed mk_product_series_rule from its title.
	// Default code for this installation is "1".
	_, _ = pg.Exec(`
INSERT INTO dfgrp (code, title, is_active, typ, master, parent_filter, sort_order, is_required, notes)
SELECT '1', '', TRUE, 'opt', 'zbggseri', '', 0, FALSE, 'auto-created fallback series'
WHERE NOT EXISTS (
  SELECT 1 FROM dfgrp WHERE master='zbggseri' AND code='1'
)
`)

	_, err := pg.Exec(`
INSERT INTO mk_product_series_rule (series_id, size_group, size_code, ratio_qty, priority, source, notes)
SELECT d.id, '', BTRIM(x.size_code), 1, 0, 'dfgrp_title', 'auto-seeded from dfgrp.title'
FROM dfgrp d
CROSS JOIN LATERAL regexp_split_to_table(COALESCE(d.title, ''), '-') AS x(size_code)
WHERE d.master='zbggseri'
  AND COALESCE(d.code,'') <> '1'
  AND BTRIM(x.size_code) <> ''
ON CONFLICT (series_id, size_group, size_code) DO NOTHING
`)
	return err
}
