create table if not exists region (
    code          varchar(10) primary key,
    sido_code     varchar(2)  not null,
    sigungu_code  varchar(3)  not null,
    dong_code     varchar(5)  not null ,
    sido_name     varchar(20) not null,
    sigungu_name  varchar(20) not null,
    dong_name     varchar(20) not null
);

create table if not exists members
(
    member_id        bigint        primary key,
    email            varchar(255)  not null,
    name             varchar(255)  not null,
    password         varchar(255)  not null,
    role             varchar(20)   not null,
    created_at       datetime(6)   null,
    last_modified_at datetime(6)   null
);

create table if not exists themes
(
    theme_id         bigint       primary key,
    description      varchar(255) not null,
    name             varchar(255) not null,
    thumbnail        varchar(255) not null,
    created_at       datetime(6)  null,
    last_modified_at datetime(6)  null
);

create table if not exists theme (
    id                     bigint       primary key ,
    name                   varchar(30)  not null,
    difficulty             varchar(20)  not null,
    description            varchar(255) not null,
    thumbnail_url          varchar(255) not null,
    price                  int          not null,
    min_participants       smallint     not null,
    max_participants       smallint     not null,
    available_minutes      smallint     not null,
    expected_minutes_from  smallint     not null,
    expected_minutes_to    smallint     not null,
    is_open                tinyint(1)   not null,
    created_at             datetime(6)  not null,
    created_by             bigint       not null,
    updated_at             datetime(6)  not null,
    updated_by             bigint       not null,

    constraint fk_theme__created_by foreign key (created_by) references members (member_id),
    constraint fk_theme__updated_by foreign key (updated_by) references members (member_id)
);

create table if not exists schedule (
    id          bigint       primary key,
    date        date         not null,
    time        time         not null,
    theme_id    bigint       not null,
    status      varchar(30)  not null,
    created_at  datetime(6)  not null,
    created_by  bigint       not null,
    updated_at  datetime(6)  not null,
    updated_by  bigint       not null,

    constraint uk_schedule__date_time_theme_id unique (date, time, theme_id),
    constraint fk_schedule__created_by foreign key (created_by) references members (member_id),
    constraint fk_schedule__updated_by foreign key (updated_by) references members (member_id),
    constraint fk_schedule__theme_id foreign key (theme_id) references theme (id)
);

create table if not exists times
(
    time_id          bigint      primary key,
    start_at         time(6)     not null,
    created_at       datetime(6) null,
    last_modified_at datetime(6) null
);

create table if not exists reservations
(
    reservation_id     bigint      primary key,
    date               date        not null,
    member_id          bigint      not null,
    theme_id           bigint      not null,
    time_id            bigint      not null,
    status             varchar(30) not null,
    created_at         datetime(6) null,
    last_modified_at   datetime(6) null,
    constraint fk_reservations__themeId foreign key (theme_id) references themes (theme_id),
    constraint fk_reservations__memberId foreign key (member_id) references members (member_id),
    constraint fk_reservations__timeId foreign key (time_id) references times (time_id)
);

create table if not exists payments
(
    payment_id       bigint       primary key,
    approved_at      datetime(6)  not null,
    reservation_id   bigint       not null,
    total_amount     bigint       not null,
    order_id         varchar(255) not null,
    payment_key      varchar(255) not null,
    created_at       datetime(6)  null,
    last_modified_at datetime(6)  null,
    constraint uk_payments__reservationId unique (reservation_id),
    constraint fk_payments__reservationId foreign key (reservation_id) references reservations (reservation_id)
);

create table if not exists canceled_payments
(
    canceled_payment_id bigint       primary key,
    payment_key         varchar(255) not null,
    cancel_reason       varchar(255) not null,
    cancel_amount       bigint       not null,
    approved_at         datetime(6)  not null,
    canceled_at         datetime(6)  not null,
    created_at          datetime(6)  null,
    last_modified_at    datetime(6)  null
);


create table if not exists payment1
(
    id              bigint       primary key,
    reservation_id  bigint       not null,
    type            varchar(20)  not null,
    method          varchar(30)  not null,
    payment_key     varchar(255) not null unique,
    order_id        varchar(255) not null unique,
    total_amount    integer      not null,
    status          varchar(20)  not null,
    requested_at    datetime(6)  not null,
    approved_at     datetime(6),

    constraint uk_payment__reservationId unique (reservation_id),
    constraint fk_payment__reservationId foreign key (reservation_id) references reservations (reservation_id)
);

create table if not exists payment_detail
(
    id               bigint     primary key,
    payment_id       bigint     not null unique,
    supplied_amount  integer    not null,
    vat              integer    not null,

    constraint fk_payment_detail__paymentId foreign key (payment_id) references payment1 (id)
);

create table if not exists payment_bank_transfer_detail
(
    id                bigint      primary key,
    bank_code         varchar(10) not null,
    settlement_status varchar(20) not null,

    constraint fk_payment_bank_transfer_details__id foreign key (id) references payment_detail (id)
);

create table if not exists payment_card_detail
(
    id	                        bigint        primary key,
    issuer_code                 varchar(10)   not null,
    card_type                   varchar(10)   not null,
    owner_type                  varchar(10)   not null,
    amount                      integer       not null,
    card_number                 varchar(20)   not null,
    approval_number             varchar(8)    not null, -- 실제로는 unique 이지만 테스트 결제 위젯에서는 항상 000000으로 동일한 값이 나옴.
    installment_plan_months     tinyint       not null,
    is_interest_free            boolean       not null,
    easypay_provider_code       varchar(20),
    easypay_discount_amount     integer,

    constraint fk_payment_card_detail__id foreign key (id) references payment_detail (id)
);

create table if not exists payment_easypay_prepaid_detail
(
    id                    bigint      primary key,
    easypay_provider_code varchar(20) not null,
    amount                integer     not null,
    discount_amount       integer     not null,

    constraint fk_payment_easypay_prepaid_detail__id foreign key (id) references payment_detail (id)
);

create table if not exists canceled_payment1
(
    id                        bigint        primary key,
    payment_id                bigint        not null,
    requested_at              datetime(6)   not null,
    canceled_at               datetime(6)   not null,
    canceled_by               bigint        not null,
    cancel_reason             varchar(255)  not null,
    cancel_amount             integer       not null,
    card_discount_amount      integer       not null,
    transfer_discount_amount  integer       not null,
    easypay_discount_amount   integer       not null,

    constraint uk_canceled_payment1__paymentId unique (payment_id),
    constraint fk_canceled_payment__paymentId  foreign key (payment_id)  references payment1(id),
    constraint fk_canceled_payment__canceledBy foreign key (canceled_by) references members(member_id)
);
