-- HotelSync Database Schema
-- Migration 001 — Initial Schema

CREATE EXTENSION IF NOT EXISTS "pgcrypto";

-- ── Hotels ─────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS hotels (
  id          UUID         PRIMARY KEY DEFAULT gen_random_uuid(),
  name        VARCHAR(255) NOT NULL,
  slug        VARCHAR(100) NOT NULL UNIQUE,
  plan        VARCHAR(20)  NOT NULL DEFAULT 'starter'
                CHECK (plan IN ('starter', 'pro', 'enterprise')),
  timezone    VARCHAR(50)  NOT NULL DEFAULT 'Europe/Moscow',
  currency    VARCHAR(3)   NOT NULL DEFAULT 'RUB',
  created_at  TIMESTAMPTZ  NOT NULL DEFAULT NOW(),
  updated_at  TIMESTAMPTZ  NOT NULL DEFAULT NOW()
);

-- ── Users ──────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS users (
  id            UUID         PRIMARY KEY DEFAULT gen_random_uuid(),
  hotel_id      UUID         REFERENCES hotels(id) ON DELETE SET NULL,
  email         VARCHAR(255) NOT NULL UNIQUE,
  password_hash VARCHAR(255) NOT NULL,
  name          VARCHAR(255) NOT NULL,
  role          VARCHAR(20)  NOT NULL DEFAULT 'manager'
                  CHECK (role IN ('manager', 'housekeeper', 'super_admin')),
  created_at    TIMESTAMPTZ  NOT NULL DEFAULT NOW(),
  updated_at    TIMESTAMPTZ  NOT NULL DEFAULT NOW()
);

-- ── Rooms ──────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS rooms (
  id              UUID          PRIMARY KEY DEFAULT gen_random_uuid(),
  hotel_id        UUID          NOT NULL REFERENCES hotels(id) ON DELETE CASCADE,
  number          VARCHAR(20)   NOT NULL,
  type            VARCHAR(50)   NOT NULL,
  floor           INTEGER       NOT NULL DEFAULT 1,
  capacity        INTEGER       NOT NULL DEFAULT 2,
  price_per_night DECIMAL(10,2) NOT NULL,
  status          VARCHAR(20)   NOT NULL DEFAULT 'clean'
                    CHECK (status IN ('clean', 'dirty', 'maintenance', 'out_of_order')),
  amenities       TEXT[]        NOT NULL DEFAULT '{}',
  notes           TEXT,
  created_at      TIMESTAMPTZ   NOT NULL DEFAULT NOW(),
  updated_at      TIMESTAMPTZ   NOT NULL DEFAULT NOW(),
  UNIQUE(hotel_id, number)
);

-- ── Bookings ───────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS bookings (
  id           UUID          PRIMARY KEY DEFAULT gen_random_uuid(),
  hotel_id     UUID          NOT NULL REFERENCES hotels(id) ON DELETE CASCADE,
  room_id      UUID          NOT NULL REFERENCES rooms(id),
  guest_name   VARCHAR(255)  NOT NULL,
  guest_email  VARCHAR(255),
  guest_phone  VARCHAR(50),
  check_in     DATE          NOT NULL,
  check_out    DATE          NOT NULL,
  adults       INTEGER       NOT NULL DEFAULT 1,
  children     INTEGER       NOT NULL DEFAULT 0,
  status       VARCHAR(20)   NOT NULL DEFAULT 'confirmed'
                 CHECK (status IN ('confirmed', 'checked_in', 'checked_out', 'cancelled', 'no_show')),
  source       VARCHAR(20)   NOT NULL DEFAULT 'direct'
                 CHECK (source IN ('direct', 'booking_com', 'airbnb', 'expedia', 'vrbo')),
  total_amount DECIMAL(10,2),
  notes        TEXT,
  external_id  VARCHAR(255),
  created_at   TIMESTAMPTZ   NOT NULL DEFAULT NOW(),
  updated_at   TIMESTAMPTZ   NOT NULL DEFAULT NOW()
);

-- ── Housekeeping Tasks ─────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS housekeeping_tasks (
  id           UUID         PRIMARY KEY DEFAULT gen_random_uuid(),
  hotel_id     UUID         NOT NULL REFERENCES hotels(id) ON DELETE CASCADE,
  room_id      UUID         REFERENCES rooms(id) ON DELETE SET NULL,
  type         VARCHAR(30)  NOT NULL DEFAULT 'cleaning'
                 CHECK (type IN ('cleaning', 'turnover', 'inspection', 'maintenance', 'amenities')),
  status       VARCHAR(20)  NOT NULL DEFAULT 'pending'
                 CHECK (status IN ('pending', 'in_progress', 'done', 'skipped')),
  priority     VARCHAR(10)  NOT NULL DEFAULT 'medium'
                 CHECK (priority IN ('low', 'medium', 'high', 'urgent')),
  assignee_id  UUID         REFERENCES users(id) ON DELETE SET NULL,
  notes        TEXT,
  due_date     DATE,
  completed_at TIMESTAMPTZ,
  created_at   TIMESTAMPTZ  NOT NULL DEFAULT NOW(),
  updated_at   TIMESTAMPTZ  NOT NULL DEFAULT NOW()
);

-- ── Channels ───────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS channels (
  id                UUID         PRIMARY KEY DEFAULT gen_random_uuid(),
  hotel_id          UUID         NOT NULL REFERENCES hotels(id) ON DELETE CASCADE,
  name              VARCHAR(50)  NOT NULL
                      CHECK (name IN ('booking_com', 'airbnb', 'expedia', 'vrbo')),
  enabled           BOOLEAN      NOT NULL DEFAULT false,
  api_key_encrypted TEXT,
  hotel_external_id VARCHAR(255),
  last_synced_at    TIMESTAMPTZ,
  created_at        TIMESTAMPTZ  NOT NULL DEFAULT NOW(),
  updated_at        TIMESTAMPTZ  NOT NULL DEFAULT NOW(),
  UNIQUE(hotel_id, name)
);

-- ── Indexes ────────────────────────────────────────────────────────────────
CREATE INDEX IF NOT EXISTS idx_bookings_hotel_dates ON bookings(hotel_id, check_in, check_out);
CREATE INDEX IF NOT EXISTS idx_bookings_room        ON bookings(room_id);
CREATE INDEX IF NOT EXISTS idx_rooms_hotel          ON rooms(hotel_id);
CREATE INDEX IF NOT EXISTS idx_tasks_hotel          ON housekeeping_tasks(hotel_id);
CREATE INDEX IF NOT EXISTS idx_users_email          ON users(email);
CREATE INDEX IF NOT EXISTS idx_users_hotel          ON users(hotel_id);
