-- Script de creación de base de datos para el sistema de condominio
-- Ejecutar en MySQL 8+ (utf8mb4)

CREATE DATABASE IF NOT EXISTS condominio CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE condominio;

-- Usuarios (administradores y clientes)
CREATE TABLE IF NOT EXISTS usuarios (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nombre_completo VARCHAR(120) NOT NULL,
  correo VARCHAR(160) NOT NULL UNIQUE,
  telefono VARCHAR(40),
  whatsapp VARCHAR(40),
  documento VARCHAR(60),
  rol ENUM('admin','cliente') DEFAULT 'cliente',
  hash_clave VARCHAR(255) NOT NULL,
  creado_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Proveedores
CREATE TABLE IF NOT EXISTS proveedores (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nombre VARCHAR(120) NOT NULL,
  rnc VARCHAR(20),
  telefono VARCHAR(40),
  correo VARCHAR(160),
  direccion VARCHAR(255),
  contacto VARCHAR(120),
  notas TEXT,
  estado ENUM('activo','inactivo') DEFAULT 'activo',
  creado_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Edificios
CREATE TABLE IF NOT EXISTS edificios (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nombre VARCHAR(120) NOT NULL,
  codigo VARCHAR(40) UNIQUE,
  direccion VARCHAR(255),
  niveles INT DEFAULT 1,
  cantidad_apartamentos INT DEFAULT 0,
  encargado_id INT,
  notas TEXT,
  FOREIGN KEY (encargado_id) REFERENCES usuarios(id) ON DELETE SET NULL
);

-- Tipos de apartamento
CREATE TABLE IF NOT EXISTS tipos_apartamento (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nombre VARCHAR(80) NOT NULL,
  descripcion TEXT,
  cuota_base DECIMAL(12,2) DEFAULT 0,
  parqueos_por_defecto INT DEFAULT 1,
  lockers_por_defecto INT DEFAULT 0
);

-- Apartamentos
CREATE TABLE IF NOT EXISTS apartamentos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  edificio_id INT NOT NULL,
  numero VARCHAR(20) NOT NULL,
  nivel INT DEFAULT 1,
  tipo_id INT,
  propietario_id INT,
  inquilino_id INT,
  parqueos INT DEFAULT 1,
  lockers INT DEFAULT 0,
  cuota_mantenimiento DECIMAL(12,2) DEFAULT 0,
  gas_incluido TINYINT(1) DEFAULT 1,
  luz_incluida TINYINT(1) DEFAULT 0,
  agua_incluida TINYINT(1) DEFAULT 1,
  basura_incluida TINYINT(1) DEFAULT 1,
  estado ENUM('activo','inactivo') DEFAULT 'activo',
  UNIQUE KEY uq_apartamento (edificio_id, numero),
  FOREIGN KEY (edificio_id) REFERENCES edificios(id) ON DELETE CASCADE,
  FOREIGN KEY (tipo_id) REFERENCES tipos_apartamento(id) ON DELETE SET NULL,
  FOREIGN KEY (propietario_id) REFERENCES usuarios(id) ON DELETE SET NULL,
  FOREIGN KEY (inquilino_id) REFERENCES usuarios(id) ON DELETE SET NULL
);

-- Áreas comunes
CREATE TABLE IF NOT EXISTS areas_comunes (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nombre VARCHAR(120) NOT NULL,
  descripcion TEXT,
  reglas TEXT
);

-- Reservas de áreas comunes
CREATE TABLE IF NOT EXISTS reservas_areas (
  id INT AUTO_INCREMENT PRIMARY KEY,
  area_id INT NOT NULL,
  apartamento_id INT NOT NULL,
  solicitante_id INT,
  inicio DATETIME NOT NULL,
  fin DATETIME NOT NULL,
  estado ENUM('pendiente','aprobada','rechazada','cancelada') DEFAULT 'pendiente',
  notas TEXT,
  creado_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (area_id) REFERENCES areas_comunes(id) ON DELETE CASCADE,
  FOREIGN KEY (apartamento_id) REFERENCES apartamentos(id) ON DELETE CASCADE,
  FOREIGN KEY (solicitante_id) REFERENCES usuarios(id) ON DELETE SET NULL,
  CONSTRAINT chk_reserva_tiempo CHECK (inicio < fin)
);

-- Novedades / sugerencias
CREATE TABLE IF NOT EXISTS novedades (
  id INT AUTO_INCREMENT PRIMARY KEY,
  apartamento_id INT,
  creado_por INT,
  tipo VARCHAR(50) DEFAULT 'sugerencia',
  titulo VARCHAR(140) NOT NULL,
  contenido TEXT NOT NULL,
  anonima TINYINT(1) DEFAULT 0,
  creado_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (apartamento_id) REFERENCES apartamentos(id) ON DELETE SET NULL,
  FOREIGN KEY (creado_por) REFERENCES usuarios(id) ON DELETE SET NULL
);

-- Visitas
CREATE TABLE IF NOT EXISTS visitas (
  id INT AUTO_INCREMENT PRIMARY KEY,
  apartamento_id INT NOT NULL,
  nombre_visita VARCHAR(140) NOT NULL,
  documento_visita VARCHAR(60),
  hora_llegada DATETIME NOT NULL,
  contacto_anfitrion VARCHAR(80),
  placa_vehiculo VARCHAR(20),
  notas TEXT,
  registrada_por INT,
  creado_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (apartamento_id) REFERENCES apartamentos(id) ON DELETE CASCADE,
  FOREIGN KEY (registrada_por) REFERENCES usuarios(id) ON DELETE SET NULL
);

-- Encabezados de documentos (CxC, CxP, ingresos, gastos)
CREATE TABLE IF NOT EXISTS encabezados (
  id INT AUTO_INCREMENT PRIMARY KEY,
  tipo ENUM('cxc','cxp','ingreso','gasto','otro') NOT NULL,
  referencia VARCHAR(80),
  descripcion VARCHAR(255),
  fecha DATE NOT NULL,
  total DECIMAL(12,2) NOT NULL,
  impuestos DECIMAL(12,2) DEFAULT 0,
  comprobante_fiscal VARCHAR(80),
  estado ENUM('pendiente','parcial','pagado','anulado') DEFAULT 'pendiente',
  creado_por INT,
  relacionado_apartamento INT,
  creado_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (creado_por) REFERENCES usuarios(id) ON DELETE SET NULL,
  FOREIGN KEY (relacionado_apartamento) REFERENCES apartamentos(id) ON DELETE SET NULL
);

-- Detalle de documentos
CREATE TABLE IF NOT EXISTS detalles (
  id INT AUTO_INCREMENT PRIMARY KEY,
  encabezado_id INT NOT NULL,
  tipo ENUM('cxc','cxp','ingreso','gasto','otro') NOT NULL,
  concepto VARCHAR(160) NOT NULL,
  cantidad DECIMAL(12,2) DEFAULT 1,
  precio DECIMAL(12,2) DEFAULT 0,
  total DECIMAL(12,2) NOT NULL,
  FOREIGN KEY (encabezado_id) REFERENCES encabezados(id) ON DELETE CASCADE
);

-- CxC cargos
CREATE TABLE IF NOT EXISTS cxc_cargos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  numero VARCHAR(20),
  encabezado_id INT,
  apartamento_id INT NOT NULL,
  tipo_cargo VARCHAR(50) DEFAULT 'cuota_mensual',
  anio INT NOT NULL,
  mes INT NOT NULL,
  fecha_emision DATE NOT NULL,
  fecha_vencimiento DATE NOT NULL,
  monto DECIMAL(12,2) NOT NULL,
  impuesto DECIMAL(12,2) DEFAULT 0,
  total DECIMAL(12,2) NOT NULL,
  porc_mora DECIMAL(5,2) DEFAULT 0,
  mora DECIMAL(12,2) DEFAULT 0,
  estado ENUM('pendiente','parcial','pagada','anulada') DEFAULT 'pendiente',
  notas TEXT,
  UNIQUE KEY uq_cxc_periodo (apartamento_id, anio, mes),
  FOREIGN KEY (apartamento_id) REFERENCES apartamentos(id) ON DELETE CASCADE,
  FOREIGN KEY (encabezado_id) REFERENCES encabezados(id) ON DELETE SET NULL
);

-- CxC pagos
CREATE TABLE IF NOT EXISTS cxc_pagos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  numero VARCHAR(20),
  cargo_id INT NOT NULL,
  encabezado_id INT,
  tipo_pago VARCHAR(50) DEFAULT 'pago_mensualidad',
  monto DECIMAL(12,2) NOT NULL,
  fecha_pago DATE NOT NULL,
  metodo ENUM('efectivo','transferencia','cheque','tarjeta','otros') DEFAULT 'efectivo',
  referencia VARCHAR(120),
  recibido_por INT,
  notas TEXT,
  FOREIGN KEY (cargo_id) REFERENCES cxc_cargos(id) ON DELETE CASCADE,
  FOREIGN KEY (encabezado_id) REFERENCES encabezados(id) ON DELETE SET NULL,
  FOREIGN KEY (recibido_por) REFERENCES usuarios(id) ON DELETE SET NULL
);

-- CxP cargos
CREATE TABLE IF NOT EXISTS cxp_cargos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  numero VARCHAR(20),
  encabezado_id INT,
  proveedor_id INT,
  proveedor VARCHAR(120),
  tipo_cargo VARCHAR(50) DEFAULT 'factura',
  descripcion TEXT,
  monto DECIMAL(12,2) NOT NULL,
  impuesto DECIMAL(12,2) DEFAULT 0,
  total DECIMAL(12,2) NOT NULL,
  fecha_vencimiento DATE NOT NULL,
  estado ENUM('pendiente','parcial','pagada','anulada') DEFAULT 'pendiente',
  factura_numero VARCHAR(60),
  FOREIGN KEY (encabezado_id) REFERENCES encabezados(id) ON DELETE SET NULL
);

-- CxP pagos
CREATE TABLE IF NOT EXISTS cxp_pagos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  numero VARCHAR(20),
  cargo_id INT NOT NULL,
  encabezado_id INT,
  tipo_pago VARCHAR(50) DEFAULT 'pago_factura',
  monto DECIMAL(12,2) NOT NULL,
  fecha_pago DATE NOT NULL,
  metodo ENUM('efectivo','transferencia','cheque','tarjeta','otros') DEFAULT 'efectivo',
  referencia VARCHAR(120),
  notas TEXT,
  FOREIGN KEY (cargo_id) REFERENCES cxp_cargos(id) ON DELETE CASCADE,
  FOREIGN KEY (encabezado_id) REFERENCES encabezados(id) ON DELETE SET NULL
);

-- Ingresos varios (también pueden quedar en encabezados/detalles con tipo ingreso)
CREATE TABLE IF NOT EXISTS ingresos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  encabezado_id INT,
  tipo_ingreso VARCHAR(50) DEFAULT 'otros',
  fuente VARCHAR(120) NOT NULL,
  descripcion TEXT,
  monto DECIMAL(12,2) NOT NULL,
  fecha_ingreso DATE NOT NULL,
  referencia VARCHAR(80),
  notas TEXT,
  FOREIGN KEY (encabezado_id) REFERENCES encabezados(id) ON DELETE SET NULL
);

-- Gastos (también pueden quedar en encabezados/detalles con tipo gasto)
CREATE TABLE IF NOT EXISTS gastos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  encabezado_id INT,
  categoria VARCHAR(80) NOT NULL,
  descripcion TEXT,
  monto DECIMAL(12,2) NOT NULL,
  fecha_gasto DATE NOT NULL,
  proveedor VARCHAR(120),
  factura_numero VARCHAR(60),
  recurrente TINYINT(1) DEFAULT 0,
  periodo VARCHAR(20),
  notas TEXT,
  FOREIGN KEY (encabezado_id) REFERENCES encabezados(id) ON DELETE SET NULL
);

-- Pagos reportados por clientes (pendientes de confirmación)
CREATE TABLE IF NOT EXISTS pagos_reportados (
  id INT AUTO_INCREMENT PRIMARY KEY,
  persona_id INT NOT NULL,
  apartamento_id INT,
  fecha_pago DATE NOT NULL,
  concepto VARCHAR(255) NOT NULL,
  monto DECIMAL(12,2) NOT NULL,
  metodo_pago ENUM('tarjeta','deposito','transferencia') NOT NULL,
  referencia VARCHAR(100),
  comprobante_url VARCHAR(255),
  estado ENUM('pendiente','confirmado','rechazado') DEFAULT 'pendiente',
  notas_cliente TEXT,
  notas_admin TEXT,
  confirmado_por INT,
  fecha_confirmacion DATETIME,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (persona_id) REFERENCES usuarios(id) ON DELETE CASCADE,
  FOREIGN KEY (apartamento_id) REFERENCES apartamentos(id) ON DELETE SET NULL,
  FOREIGN KEY (confirmado_por) REFERENCES usuarios(id) ON DELETE SET NULL
);

-- Índices auxiliares
CREATE INDEX idx_cxc_vencimiento ON cxc_cargos(fecha_vencimiento, estado);
CREATE INDEX idx_cxp_vencimiento ON cxp_cargos(fecha_vencimiento, estado);
CREATE INDEX idx_reservas_horario ON reservas_areas(area_id, inicio, fin);
CREATE INDEX idx_novedades_apartamento ON novedades(apartamento_id);
CREATE INDEX idx_visitas_hora ON visitas(hora_llegada);
CREATE INDEX idx_pagos_reportados_estado ON pagos_reportados(estado, created_at);
