CREATE TABLE IF NOT EXISTS users (
    id BIGSERIAL PRIMARY KEY,
    first_name VARCHAR(255) NOT NULL,
    last_name VARCHAR(255) NOT NULL,
    email VARCHAR(255) UNIQUE  ,
    phone_number VARCHAR(20) UNIQUE,
    role VARCHAR(50) NOT NULL,
    password BYTEA NOT NULL,
    email_verified BOOLEAN NOT NULL DEFAULT FALSE,
    phone_verified BOOLEAN NOT NULL DEFAULT FALSE,
    created_at TIMESTAMPTZ  NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ  ,
    --
    suspended_at TIMESTAMPTZ  NULL,  -- this can be NULL if the user is not suspended
    suspended BOOLEAN NOT NULL DEFAULT FALSE,
      CHECK (email IS NOT NULL OR phone_number IS NOT NULL) 
);
CREATE TABLE refresh_tokens (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL,
    token TEXT NOT NULL UNIQUE,
    expires_at  TIMESTAMPTZ NOT NULL,
    created_at  TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL,
    revoked BOOLEAN DEFAULT FALSE NOT NULL,
    CONSTRAINT unique_token UNIQUE (token)
);
-----
   CREATE TABLE otps (
   id BIGSERIAL PRIMARY KEY,
    sent_to VARCHAR(255) NOT NULL,
    medium VARCHAR(50) NOT NULL, 
    otp_for VARCHAR(50) NOT NULL,    
    otp VARCHAR(10) NOT NULL,      
    used BOOLEAN NOT NULL DEFAULT FALSE,
    used_at TIMESTAMPTZ,         
    created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,  
    expires_at TIMESTAMPTZ NOT NULL 
);

CREATE TABLE IF NOT EXISTS bets (
	id BIGSERIAL PRIMARY KEY,
	amount BIGINT NOT NULL,
	total_odds REAL NOT NULL,
    status INT NOT NULL,
    full_name VARCHAR(255) NOT NULL,
    phone_number VARCHAR(255) NOT NULL,
    branch_id BIGINT,
    user_id BIGINT,
    cashed_out BOOLEAN DEFAULT FALSE,
	created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    is_shop_bet BOOLEAN NOT NULL,
    CHECK (user_id IS NOT NULL OR branch_id IS NOT NULL)
);

CREATE TABLE IF NOT EXISTS tickets (
	id BIGSERIAL PRIMARY KEY,
	amount BIGINT NULL,
	total_odds REAL NOT NULL,
	created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- CREATE TABLE IF NOT EXISTS bet_outcomes (
-- 	id BIGSERIAL PRIMARY KEY,
--     bet_id BIGINT NOT NULL,
-- 	outcome_id BIGINT NOT NULL,
-- );

-- CREATE TABLE IF NOT EXISTS ticket_outcomes (
-- 	id BIGSERIAL PRIMARY KEY,
--     ticket_id BIGINT NOT NULL,
-- 	outcome_id BIGINT NOT NULL,
-- );

CREATE TABLE IF NOT EXISTS wallets (
    id BIGSERIAL PRIMARY KEY,
    balance BIGINT NOT NULL DEFAULT 0,
    is_withdraw BOOLEAN NOT NULL,
    is_bettable BOOLEAN NOT NULL,
    is_transferable BOOLEAN NOT NULL,
    user_id BIGINT NOT NULL,
    is_active BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);


CREATE TABLE IF NOT EXISTS customer_wallets (
    id BIGSERIAL PRIMARY KEY,
    customer_id BIGINT NOT NULL,
    company_id BIGINT NOT NULL,
    regular_wallet_id BIGINT NOT NULL,
    static_wallet_id BIGINT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE (customer_id, company_id)
);

CREATE TABLE IF NOT EXISTS wallet_transfer (
    id BIGSERIAL PRIMARY KEY,
    amount BIGINT NOT NULL,
    type VARCHAR(255) NOT NULL,
    receiver_wallet_id BIGINT NOT NULL,
    sender_wallet_id BIGINT,
    cashier_id BIGINT,
    verified BOOLEAN NOT NULL DEFAULT false,
    payment_method VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS transactions (
    id BIGSERIAL PRIMARY KEY,
    amount BIGINT NOT NULL,
    branch_id BIGINT NOT NULL,
    cashier_id BIGINT NOT NULL,
    bet_id BIGINT NOT NULL,
    payment_option BIGINT NOT NULL,
    full_name VARCHAR(255) NOT NULL,
    phone_number VARCHAR(255) NOT NULL,
    bank_code VARCHAR(255) NOT NULL,
    beneficiary_name VARCHAR(255) NOT NULL,
    account_name VARCHAR(255) NOT NULL,
    account_number VARCHAR(255) NOT NULL,
    reference_number VARCHAR(255) NOT NULL,
    verified BOOLEAN NOT NULL DEFAULT false,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS branches (
    id BIGSERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    location VARCHAR(255) NOT NULL,
    wallet_id BIGINT NOT NULL,
    branch_manager_id BIGINT NOT NULL,
    company_id BIGINT NOT NULL,
    is_self_owned BOOLEAN NOT NULL DEFAULT false,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE VIEW branch_details AS
SELECT branches.*, 
    CONCAT(users.first_name, ' ', users.last_name) AS manager_name, 
    users.phone_number AS manager_phone_number
FROM branches
LEFT JOIN users ON branches.branch_manager_id = users.id;

CREATE TABLE IF NOT EXISTS supported_operations (
    id BIGSERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    description VARCHAR(255) NOT NULL
);

CREATE TABLE IF NOT EXISTS branch_operations (
    id BIGSERIAL PRIMARY KEY,
    operation_id BIGINT NOT NULL,
    branch_id BIGINT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

----------------------------------------------seed data-------------------------------------------------------------
-------------------------------------- DO NOT USE IN PRODUCTION-------------------------------------------------

CREATE EXTENSION IF NOT EXISTS pgcrypto;

INSERT INTO users (
    first_name, last_name, email, phone_number, password, role, 
    email_verified, phone_verified, created_at, updated_at, 
    suspended_at, suspended
) VALUES (
    'John', 
    'Doe', 
    'john.doe@example.com', 
    NULL, 
    crypt('password123', gen_salt('bf'))::bytea,  
    'customer',  
    TRUE,      
    FALSE,       
    CURRENT_TIMESTAMP, 
    CURRENT_TIMESTAMP, 
    NULL,      
    FALSE       
);


INSERT INTO supported_operations (
    name, description
) VALUES 
('SportBook', 'Sportbook operations'),
('Virtual', 'Virtual operations'),
('GameZone', 'GameZone operations')
;
