CREATE TABLE IF NOT EXISTS schema_version (
    id      INT NOT NULL PRIMARY KEY,
    version INT NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS users (
    userID             VARCHAR(64)  NOT NULL PRIMARY KEY,
    username           VARCHAR(191) NOT NULL UNIQUE,
    passwordHash       VARCHAR(255) NOT NULL,
    role               VARCHAR(32)  NOT NULL,
    entityID           VARCHAR(64)  NOT NULL,
    mustChangePassword TINYINT(1)   NOT NULL DEFAULT 1,
    createdAt          BIGINT       NOT NULL,
    CONSTRAINT chk_users_role CHECK (role IN ('admin','supervisor','coach'))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS admin (
    adminID  VARCHAR(64)  NOT NULL PRIMARY KEY,
    username VARCHAR(191) NOT NULL,
    location VARCHAR(255) NOT NULL DEFAULT ''
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS supervisor (
    supervisorID VARCHAR(64)  NOT NULL PRIMARY KEY,
    username     VARCHAR(191) NOT NULL,
    location     VARCHAR(255) NOT NULL DEFAULT ''
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS coach (
    coachID      VARCHAR(64) NOT NULL PRIMARY KEY,
    supervisorID VARCHAR(64) NOT NULL,
    username     VARCHAR(191) NOT NULL,
    FOREIGN KEY(supervisorID) REFERENCES supervisor(supervisorID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS client (
    clientCode VARCHAR(191) NOT NULL PRIMARY KEY,
    coachID    VARCHAR(64)  NOT NULL,
    archived   TINYINT(1)   NOT NULL DEFAULT 0,
    archivedAt BIGINT       NOT NULL DEFAULT 0,
    FOREIGN KEY(coachID) REFERENCES coach(coachID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS questionnaire_category (
    categoryKey VARCHAR(191) NOT NULL PRIMARY KEY,
    label       VARCHAR(255) NOT NULL DEFAULT '',
    color       VARCHAR(32)  NOT NULL DEFAULT '#64748b',
    orderIndex  INT          NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS questionnaire (
    questionnaireID    VARCHAR(191) NOT NULL PRIMARY KEY,
    name               VARCHAR(255) NOT NULL DEFAULT '',
    version            VARCHAR(64)  NOT NULL DEFAULT '',
    state              VARCHAR(64)  NOT NULL DEFAULT '',
    orderIndex         INT          NOT NULL DEFAULT 0,
    showPoints         TINYINT(1)   NOT NULL DEFAULT 0,
    conditionJson      LONGTEXT     NOT NULL,
    categoryKey        VARCHAR(191) NOT NULL DEFAULT '',
    structureRevision  INT          NOT NULL DEFAULT 1,
    structureChangedAt BIGINT       NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS questionnaire_structure_snapshot (
    questionnaireID   VARCHAR(191) NOT NULL,
    structureRevision INT          NOT NULL,
    createdAt         BIGINT       NOT NULL,
    manifestJson      LONGTEXT     NOT NULL,
    PRIMARY KEY (questionnaireID, structureRevision),
    FOREIGN KEY(questionnaireID) REFERENCES questionnaire(questionnaireID) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS question (
    questionID        VARCHAR(64)  NOT NULL PRIMARY KEY,
    questionnaireID   VARCHAR(191) NOT NULL,
    defaultText       LONGTEXT     NOT NULL,
    type              VARCHAR(64)  NOT NULL DEFAULT '',
    orderIndex        INT          NOT NULL DEFAULT 0,
    isRequired        TINYINT(1)   NOT NULL DEFAULT 0,
    configJson        LONGTEXT     NOT NULL,
    retiredAt         BIGINT       NOT NULL DEFAULT 0,
    retiredInRevision INT          NOT NULL DEFAULT 0,
    FOREIGN KEY(questionnaireID) REFERENCES questionnaire(questionnaireID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS answer_option (
    answerOptionID VARCHAR(64) NOT NULL PRIMARY KEY,
    questionID     VARCHAR(64) NOT NULL,
    defaultText    LONGTEXT    NOT NULL,
    points         INT         NOT NULL DEFAULT 0,
    orderIndex     INT         NOT NULL DEFAULT 0,
    nextQuestionId VARCHAR(64) NOT NULL DEFAULT '',
    retiredAt      BIGINT      NOT NULL DEFAULT 0,
    FOREIGN KEY(questionID) REFERENCES question(questionID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS client_answer (
    clientCode     VARCHAR(191) NOT NULL,
    questionID     VARCHAR(64)  NOT NULL,
    answerOptionID VARCHAR(64)  NULL,
    freeTextValue  LONGTEXT     NULL,
    numericValue   DOUBLE       NULL,
    answeredAt     BIGINT       NULL,
    PRIMARY KEY (clientCode, questionID),
    FOREIGN KEY(clientCode) REFERENCES client(clientCode),
    FOREIGN KEY(questionID) REFERENCES question(questionID),
    FOREIGN KEY(answerOptionID) REFERENCES answer_option(answerOptionID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS completed_questionnaire (
    clientCode      VARCHAR(191) NOT NULL,
    questionnaireID VARCHAR(191) NOT NULL,
    assignedByCoach VARCHAR(64)  NULL,
    status          VARCHAR(64)  NOT NULL DEFAULT '',
    startedAt       BIGINT       NULL,
    completedAt     BIGINT       NULL,
    sumPoints       INT          NULL,
    PRIMARY KEY (clientCode, questionnaireID),
    FOREIGN KEY(clientCode) REFERENCES client(clientCode),
    FOREIGN KEY(questionnaireID) REFERENCES questionnaire(questionnaireID),
    FOREIGN KEY(assignedByCoach) REFERENCES coach(coachID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS question_translation (
    questionID   VARCHAR(64) NOT NULL,
    languageCode VARCHAR(16) NOT NULL,
    text         LONGTEXT    NOT NULL,
    PRIMARY KEY (questionID, languageCode),
    FOREIGN KEY(questionID) REFERENCES question(questionID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS answer_option_translation (
    answerOptionID VARCHAR(64) NOT NULL,
    languageCode   VARCHAR(16) NOT NULL,
    text           LONGTEXT    NOT NULL,
    PRIMARY KEY (answerOptionID, languageCode),
    FOREIGN KEY(answerOptionID) REFERENCES answer_option(answerOptionID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS string_translation (
    stringKey    VARCHAR(191) NOT NULL,
    languageCode VARCHAR(16)  NOT NULL,
    text         LONGTEXT     NOT NULL,
    PRIMARY KEY (stringKey, languageCode)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS language (
    languageCode VARCHAR(16)  NOT NULL PRIMARY KEY,
    name         VARCHAR(191) NOT NULL DEFAULT '',
    enabled      TINYINT(1)   NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS questionnaire_language_disable (
    questionnaireID VARCHAR(191) NOT NULL,
    languageCode    VARCHAR(16)  NOT NULL,
    PRIMARY KEY (questionnaireID, languageCode),
    FOREIGN KEY(questionnaireID) REFERENCES questionnaire(questionnaireID) ON DELETE CASCADE,
    FOREIGN KEY(languageCode) REFERENCES language(languageCode) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS session (
    token     VARCHAR(128) NOT NULL PRIMARY KEY,
    userID    VARCHAR(64)  NOT NULL,
    role      VARCHAR(32)  NOT NULL,
    entityID  VARCHAR(64)  NOT NULL DEFAULT '',
    createdAt BIGINT       NOT NULL,
    expiresAt BIGINT       NOT NULL,
    temp      TINYINT(1)   NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS questionnaire_submission (
    submissionID          VARCHAR(64)  NOT NULL PRIMARY KEY,
    clientCode            VARCHAR(191) NOT NULL,
    questionnaireID     VARCHAR(191) NOT NULL,
    version               INT          NOT NULL,
    submittedAt           BIGINT       NOT NULL,
    submittedByUserID     VARCHAR(64)  NOT NULL DEFAULT '',
    submittedByRole       VARCHAR(32)  NOT NULL DEFAULT '',
    assignedByCoach       VARCHAR(64)  NULL,
    status                VARCHAR(64)  NOT NULL DEFAULT '',
    startedAt             BIGINT       NULL,
    completedAt           BIGINT       NULL,
    sumPoints             INT          NULL,
    structureRevision     INT          NOT NULL DEFAULT 1,
    structureSnapshotJson LONGTEXT     NOT NULL,
    FOREIGN KEY(clientCode) REFERENCES client(clientCode),
    FOREIGN KEY(questionnaireID) REFERENCES questionnaire(questionnaireID),
    FOREIGN KEY(assignedByCoach) REFERENCES coach(coachID),
    UNIQUE KEY uq_submission_client_qn_version (clientCode, questionnaireID, version),
    KEY idx_submission_client_qn (clientCode, questionnaireID),
    KEY idx_submission_client_time (clientCode, submittedAt)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS client_answer_submission (
    submissionID   VARCHAR(64) NOT NULL,
    questionID     VARCHAR(64) NOT NULL,
    answerOptionID VARCHAR(64) NULL,
    freeTextValue  LONGTEXT    NULL,
    numericValue   DOUBLE      NULL,
    answeredAt     BIGINT      NULL,
    PRIMARY KEY (submissionID, questionID),
    FOREIGN KEY(submissionID) REFERENCES questionnaire_submission(submissionID) ON DELETE CASCADE,
    FOREIGN KEY(questionID) REFERENCES question(questionID),
    FOREIGN KEY(answerOptionID) REFERENCES answer_option(answerOptionID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS client_followup_note (
    clientCode      VARCHAR(191) NOT NULL PRIMARY KEY,
    note            LONGTEXT     NOT NULL,
    updatedByUserID VARCHAR(64)  NOT NULL DEFAULT '',
    updatedAt       BIGINT       NOT NULL,
    FOREIGN KEY(clientCode) REFERENCES client(clientCode)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS system_setting (
    settingKey   VARCHAR(191) NOT NULL PRIMARY KEY,
    settingValue LONGTEXT     NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS question_score_rule (
    ruleID     VARCHAR(64) NOT NULL PRIMARY KEY,
    questionID VARCHAR(64) NOT NULL,
    scopeKey   VARCHAR(191) NOT NULL DEFAULT '',
    levelKey   VARCHAR(191) NOT NULL,
    points     INT         NOT NULL DEFAULT 0,
    FOREIGN KEY(questionID) REFERENCES question(questionID) ON DELETE CASCADE,
    UNIQUE KEY uq_score_rule_question_scope_level (questionID, scopeKey, levelKey),
    KEY idx_score_rule_question (questionID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS scoring_profile (
    profileID            VARCHAR(64)  NOT NULL PRIMARY KEY,
    name                 VARCHAR(255) NOT NULL DEFAULT '',
    description          LONGTEXT     NOT NULL,
    isActive             TINYINT(1)   NOT NULL DEFAULT 1,
    greenMin             INT          NOT NULL DEFAULT 0,
    greenMax             INT          NOT NULL DEFAULT 12,
    yellowMin            INT          NOT NULL DEFAULT 13,
    yellowMax            INT          NOT NULL DEFAULT 36,
    redMin               INT          NOT NULL DEFAULT 37,
    processCompleteBands LONGTEXT     NOT NULL,
    createdAt            BIGINT       NOT NULL DEFAULT 0,
    updatedAt            BIGINT       NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS scoring_profile_questionnaire (
    profileID       VARCHAR(64)  NOT NULL,
    questionnaireID VARCHAR(191) NOT NULL,
    weight          DOUBLE       NOT NULL DEFAULT 1.0,
    orderIndex      INT          NOT NULL DEFAULT 0,
    PRIMARY KEY (profileID, questionnaireID),
    FOREIGN KEY(profileID) REFERENCES scoring_profile(profileID) ON DELETE CASCADE,
    FOREIGN KEY(questionnaireID) REFERENCES questionnaire(questionnaireID) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS client_scoring_profile_result (
    clientCode            VARCHAR(191) NOT NULL,
    profileID             VARCHAR(64)  NOT NULL,
    weightedTotal         DOUBLE       NOT NULL DEFAULT 0,
    band                  VARCHAR(32)  NOT NULL DEFAULT '',
    computedAt            BIGINT       NOT NULL DEFAULT 0,
    questionnaireSnapshot LONGTEXT     NOT NULL,
    coachBand             VARCHAR(32)  NOT NULL DEFAULT '',
    coachReviewedAt       BIGINT       NOT NULL DEFAULT 0,
    coachReviewedByUserID VARCHAR(64)  NOT NULL DEFAULT '',
    PRIMARY KEY (clientCode, profileID),
    FOREIGN KEY(clientCode) REFERENCES client(clientCode) ON DELETE CASCADE,
    FOREIGN KEY(profileID) REFERENCES scoring_profile(profileID) ON DELETE CASCADE,
    KEY idx_client_profile_result_profile (profileID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
