-- Lunch MiniApp MVP MySQL Schema
-- Assumption: MySQL 8.0+
-- Charset/Collation: utf8mb4

set names utf8mb4;

-- 1) users
create table if not exists app_user (
  id char(36) not null,
  provider varchar(32) not null default 'toss',
  provider_user_id varchar(128) not null,
  nick_name varchar(50) not null,
  created_at timestamp not null default current_timestamp,
  updated_at timestamp not null default current_timestamp on update current_timestamp,
  primary key (id),
  unique key uk_app_user_provider (provider, provider_user_id)
) engine=InnoDB default charset=utf8mb4 collate=utf8mb4_0900_ai_ci;

-- 2) restaurants
create table if not exists restaurant (
  id char(36) not null,
  external_place_id varchar(128) null,
  name varchar(120) not null,
  category varchar(20) not null,
  address varchar(255) not null,
  phone varchar(30) null,
  opening_hours text null,
  lat double not null,
  lng double not null,
  is_active tinyint(1) not null default 1,
  created_at timestamp not null default current_timestamp,
  updated_at timestamp not null default current_timestamp on update current_timestamp,
  primary key (id),
  unique key uk_restaurant_external_place_id (external_place_id),
  key idx_restaurant_lat_lng (lat, lng),
  key idx_restaurant_category (category),
  constraint chk_restaurant_category check (category in ('KOREAN','CHINESE','JAPANESE','WESTERN','OTHER'))
) engine=InnoDB default charset=utf8mb4 collate=utf8mb4_0900_ai_ci;

-- 3) reviews (1 user : 1 restaurant)
create table if not exists restaurant_review (
  id char(36) not null,
  restaurant_id char(36) not null,
  user_id char(36) not null,
  rating tinyint not null,
  content varchar(500) not null,
  deleted_at timestamp null,
  created_at timestamp not null default current_timestamp,
  updated_at timestamp not null default current_timestamp on update current_timestamp,
  primary key (id),
  unique key uk_review_restaurant_user (restaurant_id, user_id),
  key idx_review_restaurant_created_at (restaurant_id, created_at),
  key idx_review_user_created_at (user_id, created_at),
  constraint fk_review_restaurant foreign key (restaurant_id) references restaurant(id) on delete cascade,
  constraint fk_review_user foreign key (user_id) references app_user(id) on delete cascade,
  constraint chk_review_rating check (rating between 1 and 5)
) engine=InnoDB default charset=utf8mb4 collate=utf8mb4_0900_ai_ci;

-- 4) likes (1 user : 1 restaurant)
create table if not exists restaurant_like (
  restaurant_id char(36) not null,
  user_id char(36) not null,
  created_at timestamp not null default current_timestamp,
  primary key (restaurant_id, user_id),
  key idx_like_restaurant (restaurant_id),
  key idx_like_user (user_id),
  constraint fk_like_restaurant foreign key (restaurant_id) references restaurant(id) on delete cascade,
  constraint fk_like_user foreign key (user_id) references app_user(id) on delete cascade
) engine=InnoDB default charset=utf8mb4 collate=utf8mb4_0900_ai_ci;

-- 5) denormalized stats
create table if not exists restaurant_stat (
  restaurant_id char(36) not null,
  review_count int not null default 0,
  like_count int not null default 0,
  rating_sum int not null default 0,
  average_rating decimal(3,2) not null default 0.00,
  updated_at timestamp not null default current_timestamp on update current_timestamp,
  primary key (restaurant_id),
  constraint fk_stat_restaurant foreign key (restaurant_id) references restaurant(id) on delete cascade
) engine=InnoDB default charset=utf8mb4 collate=utf8mb4_0900_ai_ci;

-- optional seed behavior:
-- insert into restaurant_stat (restaurant_id)
-- select r.id from restaurant r
-- on duplicate key update restaurant_id = values(restaurant_id);

-- 6) stat refresh procedure (call from app service after write)
drop procedure if exists refresh_restaurant_stat;
delimiter $$
create procedure refresh_restaurant_stat(in p_restaurant_id char(36))
begin
  declare v_review_count int default 0;
  declare v_like_count int default 0;
  declare v_rating_sum int default 0;
  declare v_average decimal(3,2) default 0.00;

  select count(*), ifnull(sum(r.rating), 0)
    into v_review_count, v_rating_sum
  from restaurant_review r
  where r.restaurant_id = p_restaurant_id
    and r.deleted_at is null;

  select count(*)
    into v_like_count
  from restaurant_like l
  where l.restaurant_id = p_restaurant_id;

  if v_review_count = 0 then
    set v_average = 0.00;
  else
    set v_average = round(v_rating_sum / v_review_count, 2);
  end if;

  insert into restaurant_stat (
    restaurant_id, review_count, like_count, rating_sum, average_rating, updated_at
  ) values (
    p_restaurant_id, v_review_count, v_like_count, v_rating_sum, v_average, current_timestamp
  )
  on duplicate key update
    review_count = values(review_count),
    like_count = values(like_count),
    rating_sum = values(rating_sum),
    average_rating = values(average_rating),
    updated_at = current_timestamp;
end $$
delimiter ;
