-- ============================================================
-- SCHÉMA SUPABASE — Application Marchand de Biens
-- À exécuter dans Supabase > SQL Editor
-- ============================================================

-- Extensions
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "unaccent";

-- ============================================================
-- TABLES PRINCIPALES
-- ============================================================

-- Profil utilisateur (complète auth.users de Supabase)
CREATE TABLE public.profiles (
  id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
  nom TEXT,
  prenom TEXT,
  telephone TEXT,
  raison_sociale TEXT,        -- Nom de la société (SCI, SARL, etc.)
  siret TEXT,
  taux_credit_defaut DECIMAL(5,3) DEFAULT 3.5,  -- Taux crédit par défaut en %
  taux_impot_defaut DECIMAL(5,3) DEFAULT 25.0,  -- Taux IS par défaut en %
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- ============================================================
-- MODULE PROSPECTION / BIENS
-- ============================================================

-- Étapes du pipeline (customisables)
CREATE TABLE public.etapes_pipeline (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  nom TEXT NOT NULL,
  ordre INTEGER NOT NULL,
  couleur TEXT DEFAULT '#6B7280',
  is_terminal BOOLEAN DEFAULT FALSE,  -- Étape finale (Vendu, Abandonné)
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Biens immobiliers
CREATE TABLE public.biens (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  etape_id UUID REFERENCES public.etapes_pipeline(id),

  -- Identification
  titre TEXT,                          -- Nom court ex: "T3 Bordeaux Caudéran"
  reference TEXT UNIQUE,               -- Référence interne auto-générée
  type_bien TEXT,                      -- appartement, maison, immeuble, terrain, local_commercial, parking

  -- Localisation
  adresse TEXT,
  code_postal TEXT,
  ville TEXT,
  departement TEXT,
  latitude DECIMAL(10,7),
  longitude DECIMAL(10,7),

  -- Caractéristiques physiques
  surface_habitable DECIMAL(8,2),       -- m² loi Carrez
  surface_totale DECIMAL(8,2),          -- m² totaux
  nb_pieces INTEGER,
  nb_chambres INTEGER,
  nb_etages INTEGER,
  etage INTEGER,
  annee_construction INTEGER,
  dpe_lettre TEXT,                      -- A, B, C, D, E, F, G
  dpe_valeur INTEGER,                   -- kWh/m²/an
  ges_lettre TEXT,
  ges_valeur INTEGER,

  -- Source
  source TEXT,                          -- particulier, agence, notaire, tribunal, succession, autre
  source_contact_id UUID,               -- Lien vers contact (notaire, agent...)
  url_annonce TEXT,

  -- Statut
  statut TEXT DEFAULT 'actif',          -- actif, abandonné, vendu
  priorite INTEGER DEFAULT 2,           -- 1=haute, 2=normale, 3=basse
  is_off_market BOOLEAN DEFAULT FALSE,

  -- Dates importantes
  date_premiere_visite DATE,
  date_offre DATE,
  date_compromis DATE,
  date_acte DATE,
  date_mise_en_vente DATE,
  date_acte_revente DATE,

  -- Notes
  description TEXT,
  points_forts TEXT,
  points_faibles TEXT,

  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Analyse financière par bien
CREATE TABLE public.analyses_financieres (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  bien_id UUID NOT NULL REFERENCES public.biens(id) ON DELETE CASCADE,
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,

  -- Acquisition
  prix_achat DECIMAL(12,2),
  type_bien_fiscal TEXT DEFAULT 'ancien',  -- ancien (7.5%) ou neuf (2%)
  frais_notaire DECIMAL(12,2),             -- calculé ou saisi manuellement
  frais_agence_achat DECIMAL(12,2),
  frais_agence_achat_pct DECIMAL(5,2),

  -- Financement
  apport DECIMAL(12,2),
  montant_emprunt DECIMAL(12,2),
  taux_credit DECIMAL(5,3),
  duree_credit_mois INTEGER,
  mensualite DECIMAL(10,2),

  -- Travaux
  budget_travaux DECIMAL(12,2),
  reserve_imprevus_pct DECIMAL(5,2) DEFAULT 10,

  -- Portage
  duree_portage_mois INTEGER DEFAULT 12,
  taxe_fonciere_annuelle DECIMAL(10,2),
  charges_copropriete_mensuelle DECIMAL(10,2),
  assurance_mensuelle DECIMAL(10,2),
  frais_divers_mensuel DECIMAL(10,2),

  -- Revente
  prix_revente_cible DECIMAL(12,2),
  frais_agence_vente_pct DECIMAL(5,2) DEFAULT 5,
  frais_agence_vente DECIMAL(12,2),
  taux_impot DECIMAL(5,2) DEFAULT 25,

  -- Résultats calculés (mis à jour automatiquement)
  prix_revient DECIMAL(12,2),
  frais_portage_total DECIMAL(12,2),
  marge_brute DECIMAL(12,2),
  marge_brute_pct DECIMAL(7,2),
  marge_nette DECIMAL(12,2),
  marge_nette_pct DECIMAL(7,2),

  -- Scénarios
  scenario_pessimiste_prix DECIMAL(12,2),
  scenario_optimiste_prix DECIMAL(12,2),

  notes TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- ============================================================
-- MODULE CONTACTS / ANNUAIRE
-- ============================================================

CREATE TABLE public.contacts (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,

  -- Identité
  nom TEXT NOT NULL,
  prenom TEXT,
  societe TEXT,
  poste TEXT,

  -- Catégorie
  categorie TEXT NOT NULL,   -- notaire, agent_immo, artisan_gros_oeuvre, artisan_second_oeuvre,
                              -- artisan_finitions, banquier, courtier, diagnostiqueur,
                              -- geometre, avocat, comptable, vendeur, acheteur, autre
  specialite TEXT,           -- ex: "Plomberie chauffage", "Électricité", "Charpente"

  -- Coordonnées
  telephone TEXT,
  telephone_2 TEXT,
  email TEXT,
  adresse TEXT,
  code_postal TEXT,
  ville TEXT,
  zone_intervention TEXT,    -- ex: "Bordeaux 33000-33100"

  -- Qualité
  note INTEGER CHECK (note BETWEEN 1 AND 5),   -- Note de 1 à 5 étoiles
  fiabilite TEXT,                               -- excellent, bon, moyen, mauvais
  recommande BOOLEAN DEFAULT FALSE,

  -- Tarification artisans
  taux_horaire DECIMAL(8,2),
  remise_habituelle_pct DECIMAL(5,2),

  notes TEXT,
  is_favori BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Lien bien ↔ contact (ex: notaire assigné à ce dossier)
CREATE TABLE public.biens_contacts (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  bien_id UUID NOT NULL REFERENCES public.biens(id) ON DELETE CASCADE,
  contact_id UUID NOT NULL REFERENCES public.contacts(id) ON DELETE CASCADE,
  role TEXT,      -- notaire_vendeur, notaire_acheteur, agent_vendeur, artisan_principal, banque
  created_at TIMESTAMPTZ DEFAULT NOW(),
  UNIQUE(bien_id, contact_id, role)
);

-- ============================================================
-- MODULE VISITES
-- ============================================================

CREATE TABLE public.visites (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  bien_id UUID NOT NULL REFERENCES public.biens(id) ON DELETE CASCADE,
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,

  date_visite TIMESTAMPTZ NOT NULL,
  duree_minutes INTEGER DEFAULT 60,
  type_visite TEXT DEFAULT 'premiere',    -- premiere, seconde, expert, contradiction

  -- Notes brutes pendant la visite
  notes_brutes TEXT,

  -- Rapport généré par IA
  rapport_genere TEXT,
  rapport_genere_at TIMESTAMPTZ,

  -- Estimations sur place
  estimation_travaux_min DECIMAL(12,2),
  estimation_travaux_max DECIMAL(12,2),
  estimation_duree_travaux_mois INTEGER,

  -- Avis global
  avis_global TEXT,           -- coup_de_coeur, interessant, neutre, a_eviter
  score_opportunite INTEGER CHECK (score_opportunite BETWEEN 1 AND 10),

  contacts_presents TEXT[],   -- Noms des personnes présentes
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Check-list de visite (items configurables)
CREATE TABLE public.checklist_items (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  categorie TEXT NOT NULL,    -- structure, toiture, electricite, plomberie, isolation, humidite, exterieur, administratif
  question TEXT NOT NULL,
  description TEXT,           -- Aide / explication
  ordre INTEGER DEFAULT 0,
  is_actif BOOLEAN DEFAULT TRUE,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Réponses à la check-list pour une visite
CREATE TABLE public.checklist_reponses (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  visite_id UUID NOT NULL REFERENCES public.visites(id) ON DELETE CASCADE,
  item_id UUID NOT NULL REFERENCES public.checklist_items(id),
  reponse TEXT,               -- ok, attention, probleme, non_verifie
  note TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  UNIQUE(visite_id, item_id)
);

-- ============================================================
-- MODULE DOCUMENTS & MÉDIAS
-- ============================================================

CREATE TABLE public.photos_biens (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  bien_id UUID NOT NULL REFERENCES public.biens(id) ON DELETE CASCADE,
  visite_id UUID REFERENCES public.visites(id),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  storage_path TEXT NOT NULL,   -- chemin dans Supabase Storage
  nom TEXT,
  legende TEXT,
  categorie TEXT,               -- facade, interieur, travaux, avant, apres
  ordre INTEGER DEFAULT 0,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE public.documents_biens (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  bien_id UUID NOT NULL REFERENCES public.biens(id) ON DELETE CASCADE,
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  storage_path TEXT NOT NULL,
  nom TEXT NOT NULL,
  type_document TEXT,    -- compromis, acte, dpe, diagnostics, devis, facture, titre_propriete, autre
  date_document DATE,
  notes TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- ============================================================
-- MODULE AGENDA / TÂCHES
-- ============================================================

CREATE TABLE public.taches (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  bien_id UUID REFERENCES public.biens(id) ON DELETE SET NULL,
  contact_id UUID REFERENCES public.contacts(id) ON DELETE SET NULL,

  titre TEXT NOT NULL,
  description TEXT,
  type_tache TEXT,         -- visite, appel, email, relance, administratif, travaux, banque, autre
  priorite INTEGER DEFAULT 2,
  statut TEXT DEFAULT 'a_faire',   -- a_faire, en_cours, fait, annule

  date_echeance TIMESTAMPTZ,
  date_rappel TIMESTAMPTZ,
  date_realisation TIMESTAMPTZ,

  recurrence TEXT,         -- null, quotidien, hebdomadaire, mensuel
  is_urgent BOOLEAN DEFAULT FALSE,

  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Notes libres
CREATE TABLE public.notes_biens (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  bien_id UUID NOT NULL REFERENCES public.biens(id) ON DELETE CASCADE,
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  contenu TEXT NOT NULL,
  type_note TEXT DEFAULT 'libre',    -- libre, contact_vendeur, negociation, info_marche
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- ============================================================
-- MODULE TRAVAUX
-- ============================================================

CREATE TABLE public.devis_travaux (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  bien_id UUID NOT NULL REFERENCES public.biens(id) ON DELETE CASCADE,
  contact_id UUID REFERENCES public.contacts(id),  -- L'artisan
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,

  lot TEXT NOT NULL,        -- Gros œuvre, Électricité, Plomberie, Menuiserie, etc.
  description TEXT,
  montant_ht DECIMAL(12,2),
  taux_tva DECIMAL(5,2) DEFAULT 10,
  montant_ttc DECIMAL(12,2),

  statut TEXT DEFAULT 'en_attente',   -- en_attente, refuse, accepte, en_cours, termine, paye
  date_devis DATE,
  date_debut_prevu DATE,
  date_fin_prevu DATE,
  date_fin_reel DATE,

  storage_path_pdf TEXT,
  notes TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- ============================================================
-- DONNÉES PAR DÉFAUT
-- ============================================================

-- Étapes pipeline par défaut (seront copiées pour chaque nouvel utilisateur)
-- (géré via trigger ou Edge Function à l'inscription)

-- Check-list de visite par défaut
INSERT INTO public.checklist_items (user_id, categorie, question, description, ordre)
VALUES
  -- Sera remplacé par un trigger, voici la structure des items par défaut
  -- Ces items sont créés via la Edge Function on-user-create
  ('00000000-0000-0000-0000-000000000000', 'structure', 'Fissures visibles sur les murs porteurs ?', 'Observer les fissures en H ou diagonales, signe de mouvement de structure', 1),
  ('00000000-0000-0000-0000-000000000000', 'toiture', 'État général de la toiture ?', 'Tuiles manquantes, mousse, faîtage, chéneaux', 2),
  ('00000000-0000-0000-0000-000000000000', 'electricite', 'Tableau électrique aux normes ?', 'Vérifier disjoncteurs, présence de terre, type de tableau', 3),
  ('00000000-0000-0000-0000-000000000000', 'plomberie', 'Type de canalisations (plomb, cuivre, PVC) ?', 'Canalisations en plomb = remplacement obligatoire', 4),
  ('00000000-0000-0000-0000-000000000000', 'humidite', 'Traces d''humidité ou de moisissures ?', 'Vérifier les angles, sous les fenêtres, la cave', 5),
  ('00000000-0000-0000-0000-000000000000', 'isolation', 'Type et état de l''isolation ?', 'Combles, murs, sol. DPE cohérent avec le ressenti', 6),
  ('00000000-0000-0000-0000-000000000000', 'exterieur', 'État des menuiseries extérieures ?', 'Simple ou double vitrage, état des joints, volets', 7),
  ('00000000-0000-0000-0000-000000000000', 'administratif', 'Charges de copropriété et procédures en cours ?', 'Demander les 3 derniers PV d''AG, montant des charges', 8);

-- ============================================================
-- ROW LEVEL SECURITY (RLS)
-- ============================================================

ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.biens ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.etapes_pipeline ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.analyses_financieres ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.contacts ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.biens_contacts ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.visites ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.checklist_items ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.checklist_reponses ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.photos_biens ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.documents_biens ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.taches ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.notes_biens ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.devis_travaux ENABLE ROW LEVEL SECURITY;

-- Politique : chaque utilisateur voit uniquement ses propres données
CREATE POLICY "user_own_data" ON public.profiles FOR ALL USING (auth.uid() = id);
CREATE POLICY "user_own_data" ON public.biens FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "user_own_data" ON public.etapes_pipeline FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "user_own_data" ON public.analyses_financieres FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "user_own_data" ON public.contacts FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "user_own_data" ON public.visites FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "user_own_data" ON public.taches FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "user_own_data" ON public.notes_biens FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "user_own_data" ON public.devis_travaux FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "user_own_data" ON public.photos_biens FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "user_own_data" ON public.documents_biens FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "user_own_data" ON public.checklist_items FOR ALL USING (auth.uid() = user_id);

-- biens_contacts : visible si l'utilisateur possède le bien
CREATE POLICY "user_own_biens_contacts" ON public.biens_contacts FOR ALL 
  USING (EXISTS (SELECT 1 FROM public.biens WHERE id = bien_id AND user_id = auth.uid()));

-- checklist_reponses : visible si l'utilisateur possède la visite
CREATE POLICY "user_own_checklist_reponses" ON public.checklist_reponses FOR ALL 
  USING (EXISTS (SELECT 1 FROM public.visites WHERE id = visite_id AND user_id = auth.uid()));

-- ============================================================
-- TRIGGER : updated_at automatique
-- ============================================================

CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN NEW.updated_at = NOW(); RETURN NEW; END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER set_updated_at BEFORE UPDATE ON public.biens FOR EACH ROW EXECUTE FUNCTION update_updated_at();
CREATE TRIGGER set_updated_at BEFORE UPDATE ON public.contacts FOR EACH ROW EXECUTE FUNCTION update_updated_at();
CREATE TRIGGER set_updated_at BEFORE UPDATE ON public.visites FOR EACH ROW EXECUTE FUNCTION update_updated_at();
CREATE TRIGGER set_updated_at BEFORE UPDATE ON public.taches FOR EACH ROW EXECUTE FUNCTION update_updated_at();
CREATE TRIGGER set_updated_at BEFORE UPDATE ON public.analyses_financieres FOR EACH ROW EXECUTE FUNCTION update_updated_at();
CREATE TRIGGER set_updated_at BEFORE UPDATE ON public.devis_travaux FOR EACH ROW EXECUTE FUNCTION update_updated_at();
CREATE TRIGGER set_updated_at BEFORE UPDATE ON public.profiles FOR EACH ROW EXECUTE FUNCTION update_updated_at();

-- ============================================================
-- TRIGGER : Créer profil + données par défaut à l'inscription
-- ============================================================

CREATE OR REPLACE FUNCTION handle_new_user()
RETURNS TRIGGER AS $$
DECLARE
  etape_ids UUID[];
BEGIN
  -- Créer le profil
  INSERT INTO public.profiles (id) VALUES (NEW.id);

  -- Créer les étapes du pipeline par défaut
  INSERT INTO public.etapes_pipeline (user_id, nom, ordre, couleur) VALUES
    (NEW.id, 'Piste', 1, '#6B7280'),
    (NEW.id, 'En analyse', 2, '#3B82F6'),
    (NEW.id, 'Offre faite', 3, '#F59E0B'),
    (NEW.id, 'Compromis signé', 4, '#8B5CF6'),
    (NEW.id, 'Acte signé', 5, '#10B981'),
    (NEW.id, 'En travaux', 6, '#F97316'),
    (NEW.id, 'En vente', 7, '#EC4899'),
    (NEW.id, 'Vendu', 8, '#22C55E'),
    (NEW.id, 'Abandonné', 9, '#EF4444');

  -- Copier la check-list de visite par défaut
  INSERT INTO public.checklist_items (user_id, categorie, question, description, ordre)
  SELECT NEW.id, categorie, question, description, ordre
  FROM public.checklist_items
  WHERE user_id = '00000000-0000-0000-0000-000000000000';

  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

CREATE TRIGGER on_auth_user_created
  AFTER INSERT ON auth.users
  FOR EACH ROW EXECUTE FUNCTION handle_new_user();

-- ============================================================
-- INDEX pour les performances
-- ============================================================

CREATE INDEX idx_biens_user_id ON public.biens(user_id);
CREATE INDEX idx_biens_etape_id ON public.biens(etape_id);
CREATE INDEX idx_biens_ville ON public.biens(ville);
CREATE INDEX idx_contacts_user_id ON public.contacts(user_id);
CREATE INDEX idx_contacts_categorie ON public.contacts(categorie);
CREATE INDEX idx_taches_user_id ON public.taches(user_id);
CREATE INDEX idx_taches_date_echeance ON public.taches(date_echeance);
CREATE INDEX idx_visites_bien_id ON public.visites(bien_id);
