
CREATE TABLE app_settings (
    setting_key VARCHAR(120) PRIMARY KEY,
    setting_value MEDIUMTEXT NULL,
    updated_at DATETIME NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE clients (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(150) NOT NULL,
    company_name VARCHAR(200) NOT NULL,
    status TINYINT(1) NOT NULL DEFAULT 1,
    created_at DATETIME NULL,
    updated_at DATETIME NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE stores (
    id INT AUTO_INCREMENT PRIMARY KEY,
    client_id INT NOT NULL,
    name VARCHAR(190) NOT NULL,
    domain VARCHAR(255) NULL,
    widget_key VARCHAR(64) NOT NULL UNIQUE,
    status TINYINT(1) NOT NULL DEFAULT 1,
    created_at DATETIME NULL,
    updated_at DATETIME NULL,
    CONSTRAINT fk_stores_client FOREIGN KEY (client_id) REFERENCES clients(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE store_topics (
    id INT AUTO_INCREMENT PRIMARY KEY,
    store_id INT NOT NULL,
    topic_code VARCHAR(80) NOT NULL,
    topic_label VARCHAR(190) NOT NULL,
    description TEXT NULL,
    is_enabled TINYINT(1) NOT NULL DEFAULT 1,
    priority INT NOT NULL DEFAULT 10,
    action_type VARCHAR(80) NOT NULL DEFAULT 'reply_only',
    source_mode VARCHAR(80) NOT NULL DEFAULT 'none',
    ask_fields VARCHAR(255) NULL,
    fallback_reply TEXT NULL,
    policy_mode VARCHAR(20) NOT NULL DEFAULT 'none',
    policy_codes TEXT NULL,
    memory_mode VARCHAR(20) NOT NULL DEFAULT 'disabled',
    memory_history_limit INT NULL,
    memory_note TEXT NULL,
    context_selector VARCHAR(255) NULL,
    context_selector_fallback VARCHAR(255) NULL,
    created_at DATETIME NULL,
    updated_at DATETIME NULL,
    UNIQUE KEY uq_store_topic (store_id, topic_code),
    CONSTRAINT fk_store_topics_store FOREIGN KEY (store_id) REFERENCES stores(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE topic_examples (
    id INT AUTO_INCREMENT PRIMARY KEY,
    topic_id INT NOT NULL,
    example_text VARCHAR(255) NOT NULL,
    sort_order INT NOT NULL DEFAULT 10,
    created_at DATETIME NULL,
    CONSTRAINT fk_topic_examples_topic FOREIGN KEY (topic_id) REFERENCES store_topics(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE topic_rules (
    id INT AUTO_INCREMENT PRIMARY KEY,
    topic_id INT NOT NULL,
    rule_group ENUM('must_do','must_not','style','escalation','data','custom') NOT NULL DEFAULT 'custom',
    rule_text TEXT NOT NULL,
    sort_order INT NOT NULL DEFAULT 10,
    created_at DATETIME NULL,
    CONSTRAINT fk_topic_rules_topic FOREIGN KEY (topic_id) REFERENCES store_topics(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE policy_blocks (
    id INT AUTO_INCREMENT PRIMARY KEY,
    store_id INT NOT NULL,
    policy_code VARCHAR(120) NOT NULL,
    title VARCHAR(190) NOT NULL,
    content MEDIUMTEXT NULL,
    created_at DATETIME NULL,
    updated_at DATETIME NULL,
    CONSTRAINT fk_policy_blocks_store FOREIGN KEY (store_id) REFERENCES stores(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE prompt_rules (
    id INT AUTO_INCREMENT PRIMARY KEY,
    store_id INT NOT NULL,
    scope VARCHAR(80) NOT NULL DEFAULT 'global',
    rule_key VARCHAR(120) NOT NULL,
    rule_value TEXT NULL,
    created_at DATETIME NULL,
    updated_at DATETIME NULL,
    UNIQUE KEY uq_store_scope_rule (store_id, scope, rule_key),
    CONSTRAINT fk_prompt_rules_store FOREIGN KEY (store_id) REFERENCES stores(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE conversation_page_events (
    id INT AUTO_INCREMENT PRIMARY KEY,
    conversation_id INT NOT NULL,
    event_type VARCHAR(50) NOT NULL DEFAULT 'page_view',
    page_url TEXT NULL,
    page_title VARCHAR(255) NULL,
    page_type VARCHAR(50) NULL,
    product_context_json MEDIUMTEXT NULL,
    created_at DATETIME NULL,
    INDEX idx_conv_page_events_conv (conversation_id),
    CONSTRAINT fk_conv_page_events_conv FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE conversation_messages (
    id INT AUTO_INCREMENT PRIMARY KEY,
    conversation_id INT NOT NULL,
    role VARCHAR(30) NOT NULL,
    message MEDIUMTEXT NOT NULL,
    created_at DATETIME NULL,
    CONSTRAINT fk_conversation_messages_conversation FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE escalations (
    id INT AUTO_INCREMENT PRIMARY KEY,
    conversation_id INT NOT NULL,
    notification_email VARCHAR(190) NULL,
    reason VARCHAR(190) NULL,
    created_at DATETIME NULL,
    CONSTRAINT fk_escalations_conversation FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE debug_logs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    store_id INT NULL,
    conversation_id INT NULL,
    level VARCHAR(20) NOT NULL DEFAULT 'info',
    source VARCHAR(80) NOT NULL,
    event VARCHAR(120) NOT NULL,
    request_data MEDIUMTEXT NULL,
    response_data MEDIUMTEXT NULL,
    error_message MEDIUMTEXT NULL,
    created_at DATETIME NULL,
    INDEX idx_debug_store (store_id),
    INDEX idx_debug_conversation (conversation_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


INSERT INTO app_settings (setting_key, setting_value, updated_at) VALUES
('mail_transport', 'mail', NOW()),
('mail_from_email', 'noreply@example.com', NOW()),
('mail_from_name', 'Smart Store Chat SaaS', NOW()),
('smtp_host', '', NOW()),
('smtp_port', '587', NOW()),
('smtp_encryption', 'tls', NOW()),
('smtp_username', '', NOW()),
('smtp_password', '', NOW()),
('smtp_timeout', '20', NOW());

INSERT INTO clients (id, name, company_name, status, created_at, updated_at) VALUES
(1, 'Demo Client', 'Demo Store SRL', 1, NOW(), NOW());

INSERT INTO stores (id, client_id, name, domain, widget_key, status, created_at, updated_at) VALUES
(1, 1, 'Wise-Computer Demo', 'wise-computer.com', 'demo_widget_key_123456', 1, NOW(), NOW());

INSERT INTO store_topics (id, store_id, topic_code, topic_label, description, is_enabled, priority, action_type, source_mode, ask_fields, fallback_reply, policy_mode, policy_codes, memory_mode, memory_history_limit, memory_note, created_at, updated_at) VALUES
(1,1,'product_search','Căutare produse','Folosit când clientul caută un produs după nume, cod, model sau piesă. Răspunsul trebuie construit doar din rezultatele găsite în Elastic produse.',1,10,'search_products','elastic_products','search_query','Nu am găsit produse pentru căutarea ta. Trimite-mi un model sau cod mai exact.','none',NULL,'disabled',0,'Nu are nevoie de istoric general. Se bazează pe întrebarea curentă și pe rezultatele din Elastic.',NOW(),NOW()),
(2,1,'product_page_qa','Întrebări din produsul curent','Folosit când clientul întreabă despre produsul aflat acum în pagină. Răspunsul trebuie să vină doar din descrierea extrasă din pagina produsului.',1,20,'answer_from_page','page_context','page_description','În descrierea curentă nu văd această informație.','none',NULL,'disabled',0,'Răspunde doar din descriere și din întrebarea actuală. Nu folosește istoric conversațional.',NOW(),NOW()),
(3,1,'product_page_missing_context','Lipsește produsul curent','Folosit când clientul cere specificații tehnice despre un produs, dar nu există context de produs în pagina curentă.',1,15,'reply_only','none','','Nu văd un produs deschis acum. Intră pe produsul dorit și repetă întrebarea, iar eu îți răspund din descrierea lui.','none',NULL,'disabled',0,'Nu are nevoie de memorie. Trebuie doar să ceară utilizatorului să intre pe produsul dorit.',NOW(),NOW()),
(4,1,'shipping_info','Informații livrare','Folosit când clientul întreabă despre costul transportului, termenul general de livrare sau alte informații generale despre transport.',1,25,'reply_only','policy_blocks','','Costul și termenul de livrare sunt definite în politicile magazinului.','single','reguli_transport','disabled',0,'Răspunde din politicile de transport ale magazinului, fără să trateze întrebarea ca status de comandă.',NOW(),NOW()),
(5,1,'order_lookup','Status comandă','Folosit când clientul întreabă despre statusul comenzii, livrare sau AWB. Poate căuta după număr de comandă sau telefon.',1,30,'search_orders','elastic_orders','order_id_or_phone','Trimite-mi numărul comenzii sau numărul de telefon folosit la comandă.','none',NULL,'enabled',6,'Păstrează memorie scurtă pentru a înțelege dacă utilizatorul răspunde cu telefon sau număr de comandă la cererea anterioară.',NOW(),NOW()),
(6,1,'return_request','Retur','Folosit când clientul vrea retur, schimb sau are produs defect. Verifică eligibilitatea pe baza comenzilor și continuă pașii de retur.',1,40,'return_flow','elastic_orders','order_id_or_phone','Pentru retur am nevoie de numărul comenzii sau de telefon.','none',NULL,'enabled',6,'Folosește memorie scurtă pentru a continua pașii de retur fără să se piardă.',NOW(),NOW()),
(7,1,'handoff','Transfer operator','Folosit când clientul cere un om, operator sau coleg. Preia telefonul și escaladează conversația către emailul magazinului.',1,50,'handoff','none','phone','Lasă-mi un număr de telefon și trimit imediat conversația unui coleg.','none',NULL,'enabled',6,'Dacă botul a cerut telefonul și clientul trimite doar cifre, tratează mesajul ca răspuns la acea cerere.',NOW(),NOW()),
(8,1,'thankyou','Mulțumiri','Folosit când clientul spune mulțumesc, mersi, merci, thanks sau închide pozitiv conversația.',1,12,'reply_only','none','','Cu drag! Dacă mai ai nevoie de ajutor, sunt aici 🙂','none',NULL,'disabled',0,'Nu are nevoie de memorie și nu trebuie să relanseze alt topic.',NOW(),NOW()),
(9,1,'fallback','Fallback controlat','Folosit când mesajul este neclar sau în afara zonelor produse, comenzi și retururi. Nu iese din context și redirecționează conversația.',1,60,'reply_only','none','','Te pot ajuta cu produse, comenzi, transport și retururi. Spune-mi ce cauți sau trimite un număr de comandă.','none',NULL,'disabled',0,'Nu are nevoie de memorie. Răspunde scurt și ține conversația în zona utilă.',NOW(),NOW());

-- Exemplele de mai jos sunt opționale și ajută doar routerul AI. Topicurile default sunt complete și fără ele.
INSERT INTO topic_examples (topic_id, example_text, sort_order, created_at) VALUES
(1,'cooler asus x550',10,NOW()),
(1,'baterie hp 250 g8',20,NOW()),
(1,'incarcator dell latitude',30,NOW()),
(1,'caut grund zinsser',40,NOW()),
(2,'ce culoare are?',10,NOW()),
(2,'în cât timp se usucă?',20,NOW()),
(2,'care e part number-ul?',30,NOW()),
(2,'cât acoperă?',40,NOW()),
(2,'poate fi folosit la exterior?',50,NOW()),
(3,'unde este comanda mea?',10,NOW()),
(3,'am comanda 15482',20,NOW()),
(3,'status comandă',30,NOW()),
(3,'awb comanda',40,NOW()),
(4,'vreau retur',10,NOW()),
(4,'produs defect, vreau sa returnez',20,NOW()),
(4,'cum fac retur?',30,NOW()),
(5,'vreau sa vorbesc cu un operator',10,NOW()),
(5,'agent',20,NOW()),
(5,'vreau un coleg',30,NOW()),
(6,'ce poți face?',10,NOW()),
(7,'ce cantitate are?',10,NOW()),
(7,'ce culoare are produsul?',20,NOW()),
(7,'cat acopera?',30,NOW()),
(7,'in cat timp se usuca?',40,NOW()),
(8,'multumesc',10,NOW()),
(8,'mersi',20,NOW()),
(8,'merci',30,NOW()),
(8,'ok multumesc',40,NOW()),
(8,'thanks',50,NOW()),
(8,'super, merci',60,NOW());

INSERT INTO topic_rules (topic_id, rule_group, rule_text, sort_order, created_at) VALUES
(1,'must_do','Folosește doar datele din Elastic produse.',10,NOW()),
(1,'must_do','Dacă nu găsești rezultate, cere modelul exact sau codul produsului.',20,NOW()),
(1,'must_not','Nu inventa compatibilități, specificații sau disponibilitate.',30,NOW()),
(1,'style','Răspunde scurt, clar și prietenos.',40,NOW()),

(2,'must_do','Răspunde doar din textul extras din selectorul paginii.',10,NOW()),
(2,'must_do','Răspunde la întrebarea actuală a clientului.',20,NOW()),
(2,'must_do','Dacă un produs are menționată utilizare exterioară, se poate utiliza și la interior; invers nu.',30,NOW()),
(2,'must_do','La orice calcul de suprafață adaugă disclaimerul: "Cantitățile pot diferi în funcție de suportul pe care sunt aplicate".',40,NOW()),
(2,'must_not','Nu inventa informații care nu apar în descriere.',50,NOW()),
(2,'must_not','Nu folosi alte surse decât descrierea extrasă din pagina curentă.',60,NOW()),
(2,'must_not','Nu lăsa istoricul conversațional să contrazică descrierea produsului.',70,NOW()),

(3,'must_do','Cere numărul comenzii sau telefonul când lipsesc datele.',10,NOW()),
(3,'must_do','Dacă există status, AWB sau date de livrare, răspunde clar și scurt.',20,NOW()),
(3,'must_not','Nu spune că ai găsit comanda dacă nu există rezultat în Elastic.',30,NOW()),

(4,'must_do','Verifică întâi comanda și apoi termenul sau statusul.',10,NOW()),
(4,'must_do','Dacă lipsesc datele de identificare, cere numărul comenzii sau telefonul.',20,NOW()),
(4,'must_not','Nu aproba returul fără să existe date suficiente.',30,NOW()),

(5,'must_do','Cere numărul de telefon dacă nu există deja.',10,NOW()),
(5,'must_do','Dacă utilizatorul a trimis deja telefonul, finalizează handoff-ul și anunță că un coleg va prelua conversația.',20,NOW()),
(5,'must_not','Nu cere telefonul din nou dacă acesta a fost deja primit.',30,NOW()),

(6,'must_do','Ține conversația doar în zona produse, comenzi și retururi.',10,NOW()),
(6,'must_do','Redirecționează politicos utilizatorul către ce poți face.',20,NOW()),
(6,'must_not','Nu ieși în subiecte generale fără legătură cu magazinul.',30,NOW()),

(7,'must_do','Dacă utilizatorul cere specificații de produs fără să existe context de produs, spune-i să intre pe produsul dorit și să repete întrebarea.',10,NOW()),
(7,'must_not','Nu inventa date despre un produs dacă nu există descrierea produsului curent.',20,NOW()),

(8,'must_do','Dacă utilizatorul exprimă mulțumire sau închide pozitiv conversația, alege acest topic.',10,NOW()),
(8,'must_do','Răspunde scurt, cald și natural.',20,NOW()),
(8,'must_not','Nu cere informații suplimentare și nu relansa topicul anterior.',30,NOW());

INSERT INTO policy_blocks (store_id, policy_code, title, content, created_at, updated_at) VALUES
(1,'reguli_transport','Reguli transport','Politică de transport:
- Livrarea standard se face în 24-48 de ore în zilele lucrătoare.
- Costul de transport este fix: 10 lei / comandă.
- Nu promite o dată exactă de livrare pentru o comandă anume fără verificare în datele comenzii.
- Dacă utilizatorul întreabă despre statusul unei comenzi, cere numărul comenzii sau telefonul și verifică separat.',NOW(),NOW());

INSERT INTO prompt_rules (store_id, scope, rule_key, rule_value, created_at, updated_at) VALUES
(1,'global','assistant_role','Ești asistentul magazinului și răspunzi doar despre produse, comenzi și retururi.',NOW(),NOW()),
(1,'global','response_style','Română naturală, scurtă și clară, ca pe WhatsApp.',NOW(),NOW()),
(1,'global','safety_rule','Dacă informația nu există în sursele primite, spune clar că nu este menționată.',NOW(),NOW()),
(1,'topic:product_search','missing_data_reply','Spune-mi modelul, codul sau denumirea produsului pe care îl cauți.',NOW(),NOW()),
(1,'topic:product_search','no_results_reply','Nu am găsit produse pentru căutarea ta. Trimite-mi un model sau cod mai exact.',NOW(),NOW()),
(1,'topic:product_search','source_error_reply','Momentan nu pot verifica produsele automat. Dacă vrei, trimite-mi modelul exact sau lasă-mi un telefon și trimit cererea unui coleg.',NOW(),NOW()),
(1,'topic:product_page_qa','missing_data_reply','Nu am primit descrierea produsului din pagină. Verifică selectorul CSS din admin.',NOW(),NOW()),
(1,'topic:product_page_qa','success_reply','În descrierea curentă nu văd această informație.',NOW(),NOW()),
(1,'topic:product_page_missing_context','success_reply','Nu văd un produs deschis acum. Intră pe produsul dorit și repetă întrebarea, iar eu îți răspund din descrierea lui.',NOW(),NOW()),
(1,'topic:shipping_info','success_reply','Livrarea standard este în 24-48 de ore în zilele lucrătoare, iar costul transportului este fix: 10 lei / comandă.',NOW(),NOW()),
(1,'topic:order_lookup','missing_data_reply','Trimite-mi numărul comenzii sau numărul de telefon folosit la comandă.',NOW(),NOW()),
(1,'topic:order_lookup','no_results_reply','Nu am găsit nicio comandă cu aceste date. Verifică numărul și mai trimite-l o dată sau lasă-mi un telefon pentru un coleg.',NOW(),NOW()),
(1,'topic:order_lookup','source_error_reply','Momentan nu am reușit să verific automat comenzile. Dacă vrei, lasă-mi un număr de telefon și trimit cererea unui coleg.',NOW(),NOW()),
(1,'topic:return_request','missing_data_reply','Pentru retur am nevoie de numărul comenzii sau de telefon.',NOW(),NOW()),
(1,'topic:return_request','source_error_reply','Momentan nu am reușit să verific returul automat. Dacă vrei, lasă-mi un număr de telefon și trimit cererea unui coleg.',NOW(),NOW()),
(1,'topic:handoff','ask_reply','Lasă-mi un număr de telefon și trimit imediat conversația unui coleg.',NOW(),NOW()),
(1,'topic:handoff','success_reply','Mulțumesc. Am trimis conversația unui coleg și vei fi contactat în cel mai scurt timp.',NOW(),NOW()),
(1,'topic:thankyou','success_reply','Cu drag! Dacă mai ai nevoie de ajutor, sunt aici 🙂',NOW(),NOW()),
(1,'topic:fallback','success_reply','Te pot ajuta cu produse, comenzi și retururi. Spune-mi ce cauți sau trimite un număr de comandă.',NOW(),NOW());



