DROP TABLE IF EXISTS "Person", "Client", "Master", "Studio", "Course", "Class", "Class_Master", "Registration", "FoodProductEnum", "FoodProduct", "Equipment", "Class_Equipment", "DrugEnum", "Drug", "DrugIntolerance", "ActivityLog";

DROP TYPE IF EXISTS "ClassType", "RegistrationStatus", "UsageType";


CREATE TYPE "UsageType" AS ENUM (
  'PayOnce',
  'PayMonthly'
);


CREATE TABLE "Person" (
  id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  full_name text NOT NULL,
  passwd_hash bytea NOT NULL
);


CREATE TABLE "Client" (
  "Person_id" int UNIQUE NOT NULL,

  phone text NOT NULL,
  email text NOT NULL,
  billing_account text NOT NULL,
  
  FOREIGN KEY ("Person_id") REFERENCES "Person" (id)
    ON DELETE CASCADE
    ON UPDATE CASCADE
);


CREATE TABLE "Master" (
  "Person_id" int UNIQUE NOT NULL,

  passport text UNIQUE NOT NULL,
  readme text NOT NULL,

  FOREIGN KEY ("Person_id") REFERENCES "Person" (id)
    ON DELETE CASCADE
    ON UPDATE CASCADE
);


CREATE TABLE "Studio" (
  id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  address text UNIQUE NOT NULL,
  capacity int NOT NULL CHECK (capacity > 0),
  begin_date timestamptz NOT NULL,
  duration interval NOT NULL,
  usage_price real NOT NULL,
  usage_type "UsageType" NOT NULL
);


CREATE TABLE "Course" (
  id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  "Master_id" int,
  name text NOT NULL,
  price real NOT NULL CHECK (price > 0),
  deadline_date timestamptz NOT NULL,

  FOREIGN KEY ("Master_id") REFERENCES "Master" ("Person_id")
    ON DELETE SET NULL
    ON UPDATE CASCADE
);


CREATE TYPE "ClassType" AS ENUM (
  'Theory',
  'Practice'
);


CREATE TABLE "Class" (
  begin_date timestamptz,
  "Course_id" int,
  "Studio_id" int,
  name text NOT NULL,
  type "ClassType" NOT NULL,
  duration interval NOT NULL,

  PRIMARY KEY (begin_date, "Course_id"),

  FOREIGN KEY ("Course_id") REFERENCES "Course" (id)
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  
  FOREIGN KEY ("Studio_id") REFERENCES "Studio" (id)
    ON DELETE SET NULL
    ON UPDATE CASCADE
);


CREATE TABLE "Class_Master" (
  "Class_begin_date" timestamptz,
  "Class_Course_id" int,
  "Master_id" int,

  PRIMARY KEY ("Class_begin_date", "Class_Course_id", "Master_id"),

  FOREIGN KEY ("Master_id") REFERENCES "Master" ("Person_id")
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  
  FOREIGN KEY ("Class_begin_date", "Class_Course_id") REFERENCES "Class" (begin_date, "Course_id")
    ON DELETE CASCADE
    ON UPDATE CASCADE
);


CREATE TYPE "RegistrationStatus" AS ENUM (
  'NotPaid',
  'Paid'
);


CREATE TABLE "Registration" (
  "Client_id" int,
  "Course_id" int,
  date timestamptz NOT NULL,
  status "RegistrationStatus" NOT NULL,

  PRIMARY KEY ("Client_id", "Course_id"),

  FOREIGN KEY ("Client_id") REFERENCES "Client" ("Person_id")
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  
  FOREIGN KEY ("Course_id") REFERENCES "Course" (id)
    ON DELETE CASCADE
    ON UPDATE CASCADE
);


CREATE TABLE "FoodProductEnum" (
  id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  name text NOT NULL,
  avg_price real NOT NULL
);


CREATE TABLE "FoodProduct" (
  id int GENERATED ALWAYS AS IDENTITY,
  "FoodProductEnum_id" int,
  "Class_begin_date" timestamptz,
  "Class_Course_id" int,
  buy_price real NOT NULL,
  buy_date timestamptz NOT NULL,
  delivery_price real NOT NULL,
  delivery_date timestamptz NOT NULL,
  expires_date timestamptz NOT NULL,

  PRIMARY KEY (id, "FoodProductEnum_id"),

  FOREIGN KEY ("FoodProductEnum_id") REFERENCES "FoodProductEnum" (id)
    ON DELETE RESTRICT
    ON UPDATE RESTRICT,
  
  FOREIGN KEY ("Class_begin_date", "Class_Course_id") REFERENCES "Class" (begin_date, "Course_id")
    ON DELETE SET NULL
    ON UPDATE CASCADE
);


CREATE TABLE "Equipment" (
  id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  "Studio_id" int,
  name text NOT NULL,
  usage_price real NOT NULL,
  usage_type "UsageType" NOT NULL,
  delivery_price real NOT NULL,
  delivery_date timestamptz NOT NULL,

  FOREIGN KEY ("Studio_id") REFERENCES "Studio" (id)
    ON DELETE SET NULL
    ON UPDATE CASCADE
);


CREATE TABLE "Class_Equipment" (
  "Class_begin_date" timestamptz,
  "Class_Course_id" int,
  "Equipment_id" int,

  PRIMARY KEY ("Class_begin_date", "Class_Course_id", "Equipment_id"),

  FOREIGN KEY ("Class_begin_date", "Class_Course_id") REFERENCES "Class" (begin_date, "Course_id")
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  
  FOREIGN KEY ("Equipment_id") REFERENCES "Equipment" (id)
    ON DELETE RESTRICT
    ON UPDATE CASCADE
);


CREATE TABLE "DrugEnum" (
  id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  name text NOT NULL,
  avg_price real NOT NULL
);


CREATE TABLE "Drug" (
  id int GENERATED ALWAYS AS IDENTITY,
  "DrugEnum_id" int,
  "Course_id" int,
  buy_price real NOT NULL,
  buy_date timestamptz NOT NULL,
  delivery_price real NOT NULL,
  delivery_date timestamptz NOT NULL,
  expires_date timestamptz NOT NULL,

  PRIMARY KEY (id, "DrugEnum_id"),

  FOREIGN KEY ("DrugEnum_id") REFERENCES "DrugEnum" (id)
    ON DELETE RESTRICT
    ON UPDATE RESTRICT,
  
  FOREIGN KEY ("Course_id") REFERENCES "Course" (id)
    ON DELETE SET NULL
    ON UPDATE CASCADE
);


CREATE TABLE "DrugIntolerance" (
  "Person_id" int,
  "DrugEnum_id" int,

  PRIMARY KEY ("Person_id", "DrugEnum_id"),

  FOREIGN KEY ("Person_id") REFERENCES "Person" (id)
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  
  FOREIGN KEY ("DrugEnum_id") REFERENCES "DrugEnum" (id)
    ON DELETE CASCADE
    ON UPDATE CASCADE
);


CREATE TABLE "ActivityLog" (
  id int GENERATED ALWAYS AS IDENTITY,
  "Person_id" int,
  action text NOT NULL,

  PRIMARY KEY (id, "Person_id"),

  FOREIGN KEY ("Person_id") REFERENCES "Person" (id)
    ON DELETE NO ACTION
    ON UPDATE CASCADE
);
