-- 006_diet_and_recipe_generators.sql
-- AI-assisted diet plan and recipe generation modules.
-- Apply after scripts 001–005.

BEGIN;

-- ---------------------------------------------------------------------------
-- User profile for TDEE / goal-based planning
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS diet."DietUserProfiles" (
    "UserId"            uuid PRIMARY KEY
                        REFERENCES diet."AspNetUsers"("Id") ON DELETE CASCADE,
    "HeightCm"          numeric(5,2) NOT NULL CHECK ("HeightCm" > 0),
    "WeightKg"          numeric(5,2) NOT NULL CHECK ("WeightKg" > 0),
    "Age"               int NOT NULL CHECK ("Age" BETWEEN 10 AND 120),
    "Sex"               varchar(16) NOT NULL CHECK ("Sex" IN ('male', 'female')),
    "ActivityLevel"     varchar(32) NOT NULL
                        CHECK ("ActivityLevel" IN ('sedentary', 'light', 'moderate', 'active', 'very_active')),
    "Goal"              varchar(32) NOT NULL
                        CHECK ("Goal" IN ('lose_weight', 'maintain', 'gain_muscle', 'recomp')),
    "AllergiesNotes"    text NULL,
    "DislikedFoods"     text NULL,
    "MealsPerDayMask"   int NOT NULL DEFAULT 15 CHECK ("MealsPerDayMask" BETWEEN 1 AND 31),
    "CreatedAt"         timestamptz NOT NULL DEFAULT now(),
    "UpdatedAt"         timestamptz NULL
);

COMMENT ON COLUMN diet."DietUserProfiles"."MealsPerDayMask" IS 'Bitmask: bit0=Breakfast, bit1=SecondBreakfast, bit2=Lunch, bit3=Dinner, bit4=Snack';

-- ---------------------------------------------------------------------------
-- Diet generator wizard sessions
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS diet."DietGeneratorSessions" (
    "Id"                    serial PRIMARY KEY,
    "UserId"                uuid NOT NULL REFERENCES diet."AspNetUsers"("Id") ON DELETE CASCADE,
    "Status"                varchar(32) NOT NULL DEFAULT 'macros_pending',
    "ProposedCalories"      int NULL CHECK ("ProposedCalories" IS NULL OR "ProposedCalories" > 0),
    "ProposedProteinG"      numeric(6,2) NULL,
    "ProposedFatG"          numeric(6,2) NULL,
    "ProposedCarbsG"        numeric(6,2) NULL,
    "MacroRationale"        text NULL,
    "MacrosAcceptedAt"      timestamptz NULL,
    "PlanStartDate"         date NULL,
    "PlanDayCount"          int NOT NULL DEFAULT 7 CHECK ("PlanDayCount" BETWEEN 1 AND 28),
    "CalorieToleranceKcal"  int NOT NULL DEFAULT 10 CHECK ("CalorieToleranceKcal" >= 0),
    "PreferencesJson"       jsonb NULL,
    "CommittedAt"           timestamptz NULL,
    "CreatedAt"             timestamptz NOT NULL DEFAULT now(),
    "UpdatedAt"             timestamptz NULL
);

CREATE INDEX IF NOT EXISTS "IX_DietGeneratorSessions_UserId_Status"
    ON diet."DietGeneratorSessions" ("UserId", "Status");

-- ---------------------------------------------------------------------------
-- Draft meals (review before commit to MealPlanEntries)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS diet."DietGeneratorDraftMeals" (
    "Id"              serial PRIMARY KEY,
    "SessionId"       int NOT NULL REFERENCES diet."DietGeneratorSessions"("Id") ON DELETE CASCADE,
    "PlanDate"        date NOT NULL,
    "MealCategory"    int NOT NULL CHECK ("MealCategory" BETWEEN 0 AND 4),
    "RecipeId"        int NOT NULL REFERENCES diet."Recipes"("Id") ON DELETE CASCADE,
    "Portions"        numeric(4,2) NOT NULL DEFAULT 1 CHECK ("Portions" > 0),
    "Calories"        int NULL,
    "ProteinG"        numeric(6,2) NULL,
    "FatG"            numeric(6,2) NULL,
    "CarbsG"          numeric(6,2) NULL,
    "IsLocked"        boolean NOT NULL DEFAULT false,
    "GenerationVersion" int NOT NULL DEFAULT 1,
    UNIQUE ("SessionId", "PlanDate", "MealCategory")
);

CREATE INDEX IF NOT EXISTS "IX_DietGeneratorDraftMeals_SessionId"
    ON diet."DietGeneratorDraftMeals" ("SessionId");

-- ---------------------------------------------------------------------------
-- Recipe generator sessions (draft JSON until commit)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS diet."RecipeGeneratorSessions" (
    "Id"                serial PRIMARY KEY,
    "UserId"            uuid NOT NULL REFERENCES diet."AspNetUsers"("Id") ON DELETE CASCADE,
    "Status"            varchar(32) NOT NULL DEFAULT 'draft',
    "ConstraintsJson"   jsonb NOT NULL DEFAULT '{}',
    "DraftJson"         jsonb NULL,
    "SavedRecipeId"     int NULL REFERENCES diet."Recipes"("Id") ON DELETE SET NULL,
    "GenerationVersion" int NOT NULL DEFAULT 1,
    "CreatedAt"         timestamptz NOT NULL DEFAULT now(),
    "UpdatedAt"         timestamptz NULL
);

CREATE INDEX IF NOT EXISTS "IX_RecipeGeneratorSessions_UserId"
    ON diet."RecipeGeneratorSessions" ("UserId");

-- ---------------------------------------------------------------------------
-- Recipe provenance (AI vs manual)
-- ---------------------------------------------------------------------------
ALTER TABLE diet."Recipes"
    ADD COLUMN IF NOT EXISTS "Source" varchar(32) NOT NULL DEFAULT 'manual';

ALTER TABLE diet."Recipes"
    ADD COLUMN IF NOT EXISTS "CreatedByUserId" uuid NULL
    REFERENCES diet."AspNetUsers"("Id") ON DELETE SET NULL;

ALTER TABLE diet."Recipes"
    ADD COLUMN IF NOT EXISTS "IsDraft" boolean NOT NULL DEFAULT false;

COMMENT ON COLUMN diet."Recipes"."Source" IS 'manual | excel | ai_generated';

COMMIT;
