-- ===========================================
-- MECANICAS DIESEL - Fiados (Credit) Schema
-- ===========================================
-- Sistema de crédito para clientes
-- Tracking de ventas a crédito y pagos

SET search_path TO service_management, public;

-- -------------------------------------------
-- CUSTOMER_CREDIT_ACCOUNTS - Cuentas de crédito
-- -------------------------------------------
CREATE TABLE IF NOT EXISTS service_management.customer_credit_accounts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,
    customer_id UUID NOT NULL REFERENCES service_management.customers(id),

    -- Límites de crédito
    credit_limit DECIMAL(12,2) DEFAULT 0 CHECK (credit_limit >= 0),
    credit_days INTEGER DEFAULT 30 CHECK (credit_days >= 0),

    -- Balances
    current_balance DECIMAL(12,2) DEFAULT 0,  -- Puede ser positivo (debe) o negativo (a favor)

    -- Estadísticas
    total_credit_given DECIMAL(14,2) DEFAULT 0,
    total_payments_received DECIMAL(14,2) DEFAULT 0,
    overdue_amount DECIMAL(12,2) DEFAULT 0,

    -- Estado
    is_active BOOLEAN DEFAULT true,
    is_frozen BOOLEAN DEFAULT false,  -- Congelar crédito si hay problemas
    frozen_reason TEXT,
    frozen_at TIMESTAMP WITH TIME ZONE,
    frozen_by UUID,

    -- Audit
    created_by UUID,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),

    CONSTRAINT uq_customer_credit_account UNIQUE (tenant_id, customer_id)
);

CREATE INDEX idx_credit_accounts_tenant ON service_management.customer_credit_accounts(tenant_id);
CREATE INDEX idx_credit_accounts_customer ON service_management.customer_credit_accounts(customer_id);
CREATE INDEX idx_credit_accounts_balance ON service_management.customer_credit_accounts(tenant_id, current_balance) WHERE current_balance > 0;
CREATE INDEX idx_credit_accounts_overdue ON service_management.customer_credit_accounts(tenant_id, overdue_amount) WHERE overdue_amount > 0;

CREATE TRIGGER trg_credit_accounts_updated_at
    BEFORE UPDATE ON service_management.customer_credit_accounts
    FOR EACH ROW EXECUTE FUNCTION trigger_set_updated_at();

-- RLS
SELECT create_tenant_rls_policies('service_management', 'customer_credit_accounts');

-- -------------------------------------------
-- FIADOS - Ventas a crédito
-- -------------------------------------------
CREATE TABLE IF NOT EXISTS service_management.fiados (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,

    -- Relaciones
    customer_id UUID NOT NULL REFERENCES service_management.customers(id),
    credit_account_id UUID NOT NULL REFERENCES service_management.customer_credit_accounts(id),
    order_id UUID REFERENCES service_management.service_orders(id),

    -- Identificación
    fiado_number VARCHAR(20) NOT NULL,

    -- Monto
    original_amount DECIMAL(12,2) NOT NULL CHECK (original_amount > 0),
    remaining_amount DECIMAL(12,2) NOT NULL CHECK (remaining_amount >= 0),

    -- Fechas
    issued_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    due_at TIMESTAMP WITH TIME ZONE NOT NULL,
    paid_at TIMESTAMP WITH TIME ZONE,

    -- Estado
    status VARCHAR(20) DEFAULT 'pending'
        CHECK (status IN ('pending', 'partial', 'paid', 'overdue', 'cancelled', 'written_off')),

    -- Descripción
    description TEXT,
    notes TEXT,

    -- Audit
    created_by UUID,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),

    CONSTRAINT uq_fiado_number UNIQUE (tenant_id, fiado_number)
);

CREATE INDEX idx_fiados_tenant ON service_management.fiados(tenant_id);
CREATE INDEX idx_fiados_customer ON service_management.fiados(customer_id);
CREATE INDEX idx_fiados_account ON service_management.fiados(credit_account_id);
CREATE INDEX idx_fiados_order ON service_management.fiados(order_id);
CREATE INDEX idx_fiados_status ON service_management.fiados(tenant_id, status);
CREATE INDEX idx_fiados_due ON service_management.fiados(due_at) WHERE status IN ('pending', 'partial');
CREATE INDEX idx_fiados_overdue ON service_management.fiados(tenant_id, due_at) WHERE status = 'overdue';

CREATE TRIGGER trg_fiados_updated_at
    BEFORE UPDATE ON service_management.fiados
    FOR EACH ROW EXECUTE FUNCTION trigger_set_updated_at();

-- RLS
SELECT create_tenant_rls_policies('service_management', 'fiados');

-- -------------------------------------------
-- FIADO_PAYMENTS - Pagos/Abonos a fiados
-- -------------------------------------------
CREATE TABLE IF NOT EXISTS service_management.fiado_payments (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,

    -- Relaciones
    customer_id UUID NOT NULL REFERENCES service_management.customers(id),
    credit_account_id UUID NOT NULL REFERENCES service_management.customer_credit_accounts(id),
    fiado_id UUID REFERENCES service_management.fiados(id),  -- NULL si es pago general a cuenta

    -- Identificación
    payment_number VARCHAR(20) NOT NULL,

    -- Monto
    amount DECIMAL(12,2) NOT NULL CHECK (amount > 0),

    -- Método de pago
    payment_method VARCHAR(20) NOT NULL
        CHECK (payment_method IN ('cash', 'card', 'transfer', 'check', 'other')),
    payment_reference VARCHAR(100),  -- Referencia de transferencia, número de cheque, etc.

    -- Descripción
    notes TEXT,

    -- Audit
    received_by UUID,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),

    CONSTRAINT uq_payment_number UNIQUE (tenant_id, payment_number)
);

CREATE INDEX idx_fiado_payments_tenant ON service_management.fiado_payments(tenant_id);
CREATE INDEX idx_fiado_payments_customer ON service_management.fiado_payments(customer_id);
CREATE INDEX idx_fiado_payments_account ON service_management.fiado_payments(credit_account_id);
CREATE INDEX idx_fiado_payments_fiado ON service_management.fiado_payments(fiado_id);
CREATE INDEX idx_fiado_payments_date ON service_management.fiado_payments(created_at DESC);

-- RLS
SELECT create_tenant_rls_policies('service_management', 'fiado_payments');

-- -------------------------------------------
-- COMMENTS
-- -------------------------------------------
COMMENT ON TABLE service_management.customer_credit_accounts IS 'Cuentas de crédito de clientes';
COMMENT ON COLUMN service_management.customer_credit_accounts.current_balance IS 'Saldo actual: positivo = cliente debe, negativo = saldo a favor';
COMMENT ON COLUMN service_management.customer_credit_accounts.is_frozen IS 'Crédito congelado por morosidad u otra razón';

COMMENT ON TABLE service_management.fiados IS 'Ventas a crédito (fiados) individuales';
COMMENT ON COLUMN service_management.fiados.fiado_number IS 'Número único de fiado (F-001, F-002, etc.)';
COMMENT ON COLUMN service_management.fiados.remaining_amount IS 'Monto pendiente de pago';
COMMENT ON COLUMN service_management.fiados.due_at IS 'Fecha de vencimiento basada en credit_days del cliente';

COMMENT ON TABLE service_management.fiado_payments IS 'Pagos/abonos recibidos para fiados';
COMMENT ON COLUMN service_management.fiado_payments.fiado_id IS 'NULL si el pago se aplica a la cuenta general, no a un fiado específico';

-- -------------------------------------------
-- VIEW: Customer Credit Summary
-- -------------------------------------------
CREATE OR REPLACE VIEW service_management.v_customer_credit_summary AS
SELECT
    ca.tenant_id,
    ca.customer_id,
    c.name AS customer_name,
    c.phone AS customer_phone,
    ca.credit_limit,
    ca.credit_days,
    ca.current_balance,
    ca.credit_limit - ca.current_balance AS available_credit,
    ca.overdue_amount,
    ca.is_active,
    ca.is_frozen,
    (SELECT COUNT(*) FROM service_management.fiados f WHERE f.credit_account_id = ca.id AND f.status IN ('pending', 'partial', 'overdue')) AS pending_fiados_count,
    (SELECT COALESCE(SUM(f.remaining_amount), 0) FROM service_management.fiados f WHERE f.credit_account_id = ca.id AND f.status = 'overdue') AS overdue_fiados_amount,
    (SELECT MAX(fp.created_at) FROM service_management.fiado_payments fp WHERE fp.credit_account_id = ca.id) AS last_payment_at
FROM service_management.customer_credit_accounts ca
JOIN service_management.customers c ON c.id = ca.customer_id;

COMMENT ON VIEW service_management.v_customer_credit_summary IS 'Resumen de crédito por cliente con estadísticas';
