-- CreateTable: referral_relationships
CREATE TABLE "referral_relationships" (
    "relationship_id" BIGSERIAL NOT NULL,
    "user_id" BIGINT NOT NULL,
    "account_sequence" INTEGER NOT NULL,
    "referrer_id" BIGINT,
    "root_user_id" BIGINT,
    "my_referral_code" VARCHAR(20) NOT NULL,
    "used_referral_code" VARCHAR(20),
    "ancestor_path" BIGINT[] NOT NULL DEFAULT '{}',
    "depth" INTEGER NOT NULL DEFAULT 0,
    "direct_referral_count" INTEGER NOT NULL DEFAULT 0,
    "active_direct_count" INTEGER NOT NULL DEFAULT 0,
    "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updated_at" TIMESTAMP(3) NOT NULL,

    CONSTRAINT "referral_relationships_pkey" PRIMARY KEY ("relationship_id")
);

-- CreateTable: team_statistics
CREATE TABLE "team_statistics" (
    "statistics_id" BIGSERIAL NOT NULL,
    "user_id" BIGINT NOT NULL,
    "direct_referral_count" INTEGER NOT NULL DEFAULT 0,
    "total_team_count" INTEGER NOT NULL DEFAULT 0,
    "self_planting_count" INTEGER NOT NULL DEFAULT 0,
    "self_planting_amount" DECIMAL(20,8) NOT NULL DEFAULT 0,
    "direct_planting_count" INTEGER NOT NULL DEFAULT 0,
    "total_team_planting_count" INTEGER NOT NULL DEFAULT 0,
    "total_team_planting_amount" DECIMAL(20,8) NOT NULL DEFAULT 0,
    "direct_team_planting_data" JSONB NOT NULL DEFAULT '[]',
    "max_single_team_planting_count" INTEGER NOT NULL DEFAULT 0,
    "effective_planting_count_for_ranking" INTEGER NOT NULL DEFAULT 0,
    "own_province_team_count" INTEGER NOT NULL DEFAULT 0,
    "own_city_team_count" INTEGER NOT NULL DEFAULT 0,
    "province_team_percentage" DECIMAL(5,2) NOT NULL DEFAULT 0,
    "city_team_percentage" DECIMAL(5,2) NOT NULL DEFAULT 0,
    "province_city_distribution" JSONB NOT NULL DEFAULT '{}',
    "last_calc_at" TIMESTAMP(3),
    "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updated_at" TIMESTAMP(3) NOT NULL,

    CONSTRAINT "team_statistics_pkey" PRIMARY KEY ("statistics_id")
);

-- CreateTable: direct_referrals
CREATE TABLE "direct_referrals" (
    "direct_referral_id" BIGSERIAL NOT NULL,
    "referrer_id" BIGINT NOT NULL,
    "referral_id" BIGINT NOT NULL,
    "referral_sequence" BIGINT NOT NULL,
    "referral_nickname" VARCHAR(100),
    "referral_avatar" VARCHAR(255),
    "personal_planting_count" INTEGER NOT NULL DEFAULT 0,
    "team_planting_count" INTEGER NOT NULL DEFAULT 0,
    "has_planted" BOOLEAN NOT NULL DEFAULT false,
    "first_planted_at" TIMESTAMP(3),
    "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updated_at" TIMESTAMP(3) NOT NULL,

    CONSTRAINT "direct_referrals_pkey" PRIMARY KEY ("direct_referral_id")
);

-- CreateTable: team_province_city_details
CREATE TABLE "team_province_city_details" (
    "detail_id" BIGSERIAL NOT NULL,
    "user_id" BIGINT NOT NULL,
    "province_code" VARCHAR(10) NOT NULL,
    "city_code" VARCHAR(10) NOT NULL,
    "team_planting_count" INTEGER NOT NULL DEFAULT 0,
    "updated_at" TIMESTAMP(3) NOT NULL,

    CONSTRAINT "team_province_city_details_pkey" PRIMARY KEY ("detail_id")
);

-- CreateTable: referral_events
CREATE TABLE "referral_events" (
    "event_id" BIGSERIAL NOT NULL,
    "event_type" VARCHAR(50) NOT NULL,
    "aggregate_id" VARCHAR(100) NOT NULL,
    "aggregate_type" VARCHAR(50) NOT NULL,
    "event_data" JSONB NOT NULL,
    "user_id" BIGINT,
    "occurred_at" TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "version" INTEGER NOT NULL DEFAULT 1,

    CONSTRAINT "referral_events_pkey" PRIMARY KEY ("event_id")
);

-- CreateIndex: referral_relationships unique constraints
CREATE UNIQUE INDEX "referral_relationships_user_id_key" ON "referral_relationships"("user_id");
CREATE UNIQUE INDEX "referral_relationships_account_sequence_key" ON "referral_relationships"("account_sequence");
CREATE UNIQUE INDEX "referral_relationships_my_referral_code_key" ON "referral_relationships"("my_referral_code");

-- CreateIndex: referral_relationships indexes
CREATE INDEX "idx_referrer" ON "referral_relationships"("referrer_id");
CREATE INDEX "idx_account_sequence" ON "referral_relationships"("account_sequence");
CREATE INDEX "idx_my_referral_code" ON "referral_relationships"("my_referral_code");
CREATE INDEX "idx_used_referral_code" ON "referral_relationships"("used_referral_code");
CREATE INDEX "idx_root_user" ON "referral_relationships"("root_user_id");
CREATE INDEX "idx_depth" ON "referral_relationships"("depth");
CREATE INDEX "idx_referral_created" ON "referral_relationships"("created_at");

-- CreateIndex: team_statistics unique constraints
CREATE UNIQUE INDEX "team_statistics_user_id_key" ON "team_statistics"("user_id");

-- CreateIndex: team_statistics indexes
CREATE INDEX "idx_leaderboard_score" ON "team_statistics"("effective_planting_count_for_ranking" DESC);
CREATE INDEX "idx_team_planting" ON "team_statistics"("total_team_planting_count" DESC);
CREATE INDEX "idx_self_planting" ON "team_statistics"("self_planting_count");

-- CreateIndex: direct_referrals unique constraints
CREATE UNIQUE INDEX "uk_referrer_referral" ON "direct_referrals"("referrer_id", "referral_id");

-- CreateIndex: direct_referrals indexes
CREATE INDEX "idx_direct_referrer" ON "direct_referrals"("referrer_id");
CREATE INDEX "idx_direct_referral" ON "direct_referrals"("referral_id");
CREATE INDEX "idx_has_planted" ON "direct_referrals"("has_planted");
CREATE INDEX "idx_direct_team_planting" ON "direct_referrals"("team_planting_count" DESC);

-- CreateIndex: team_province_city_details unique constraints
CREATE UNIQUE INDEX "uk_user_province_city" ON "team_province_city_details"("user_id", "province_code", "city_code");

-- CreateIndex: team_province_city_details indexes
CREATE INDEX "idx_detail_user" ON "team_province_city_details"("user_id");
CREATE INDEX "idx_detail_province" ON "team_province_city_details"("province_code");
CREATE INDEX "idx_detail_city" ON "team_province_city_details"("city_code");

-- CreateIndex: referral_events indexes
CREATE INDEX "idx_event_aggregate" ON "referral_events"("aggregate_type", "aggregate_id");
CREATE INDEX "idx_event_type" ON "referral_events"("event_type");
CREATE INDEX "idx_event_user" ON "referral_events"("user_id");
CREATE INDEX "idx_event_occurred" ON "referral_events"("occurred_at");

-- AddForeignKey: referral_relationships self-reference
ALTER TABLE "referral_relationships" ADD CONSTRAINT "referral_relationships_referrer_id_fkey" FOREIGN KEY ("referrer_id") REFERENCES "referral_relationships"("user_id") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey: team_statistics to referral_relationships
ALTER TABLE "team_statistics" ADD CONSTRAINT "team_statistics_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "referral_relationships"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE;
