-- =====================================================
-- Migration 005: Employee Lifecycle Platform
-- =====================================================

-- ==========================================
-- 1. CORE TABLES
-- ==========================================

-- Departments (Avdelningar)
CREATE TABLE IF NOT EXISTS departments (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES boc_tenants(id),
    name VARCHAR(100) NOT NULL,
    code VARCHAR(20),
    description TEXT,
    parent_id UUID REFERENCES departments(id),
    manager_id UUID,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_departments_tenant ON departments(tenant_id);

-- Teams
CREATE TABLE IF NOT EXISTS teams (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES boc_tenants(id),
    name VARCHAR(100) NOT NULL,
    description TEXT,
    department_id UUID REFERENCES departments(id),
    lead_id UUID,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_teams_tenant ON teams(tenant_id);
CREATE INDEX IF NOT EXISTS idx_teams_department ON teams(department_id);

-- Roles (Rolldefinitioner)
CREATE TABLE IF NOT EXISTS roles (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES boc_tenants(id),
    name VARCHAR(100) NOT NULL,
    description TEXT,
    level INTEGER DEFAULT 1, -- hierarkisk nivå
    permissions JSONB DEFAULT '[]',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_roles_tenant ON roles(tenant_id);

-- Employees (Medarbetare)
CREATE TABLE IF NOT EXISTS employees (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES boc_tenants(id),
    
    -- Personuppgifter
    first_name VARCHAR(100) NOT NULL,
    last_name VARCHAR(100) NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    phone VARCHAR(20),
    personal_number VARCHAR(20),
    birth_date DATE,
    
    -- Profil
    avatar_url VARCHAR(500),
    bio TEXT,
    
    -- Anställning
    employment_type VARCHAR(20) DEFAULT 'full_time', -- full_time, part_time, consultant, intern, contractor
    employment_status VARCHAR(20) DEFAULT 'active', -- active, probation, notice, terminated, suspended
    start_date DATE,
    end_date DATE,
    probation_end_date DATE,
    notice_period_days INTEGER DEFAULT 30,
    
    -- Organisation
    department_id UUID REFERENCES departments(id),
    team_id UUID REFERENCES teams(id),
    manager_id UUID REFERENCES employees(id),
    role_id UUID REFERENCES roles(id),
    
    -- Ekonomi
    salary DECIMAL(12,2),
    salary_currency VARCHAR(3) DEFAULT 'SEK',
    bank_account VARCHAR(50),
    bank_clearing VARCHAR(10),
    
    -- Kontakt
    address TEXT,
    postal_code VARCHAR(10),
    city VARCHAR(100),
    country VARCHAR(2) DEFAULT 'SE',
    
    -- Nödfall
    emergency_contact_name VARCHAR(100),
    emergency_contact_phone VARCHAR(20),
    emergency_contact_relation VARCHAR(50),
    
    -- Metadata
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    created_by UUID,
    version INTEGER DEFAULT 1
);

CREATE INDEX IF NOT EXISTS idx_employees_tenant ON employees(tenant_id);
CREATE INDEX IF NOT EXISTS idx_employees_department ON employees(department_id);
CREATE INDEX IF NOT EXISTS idx_employees_team ON employees(team_id);
CREATE INDEX IF NOT EXISTS idx_employees_manager ON employees(manager_id);
CREATE INDEX IF NOT EXISTS idx_employees_status ON employees(employment_status);
CREATE INDEX IF NOT EXISTS idx_employees_email ON employees(email);

-- Employee Timeline Events
CREATE TABLE IF NOT EXISTS employee_timeline_events (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    employee_id UUID NOT NULL REFERENCES employees(id) ON DELETE CASCADE,
    event_type VARCHAR(50) NOT NULL, -- hired, promoted, review, leave, termination, role_change, salary_change, etc.
    event_date DATE NOT NULL,
    title VARCHAR(255) NOT NULL,
    description TEXT,
    metadata JSONB DEFAULT '{}',
    created_by UUID,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_timeline_employee ON employee_timeline_events(employee_id);
CREATE INDEX IF NOT EXISTS idx_timeline_date ON employee_timeline_events(event_date);
CREATE INDEX IF NOT EXISTS idx_timeline_type ON employee_timeline_events(event_type);

-- ==========================================
-- 2. COMPETENCE SYSTEM
-- ==========================================

-- Competences (Kompetenser)
CREATE TABLE IF NOT EXISTS competences (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES boc_tenants(id),
    name VARCHAR(100) NOT NULL,
    category VARCHAR(50), -- technical, soft_skill, language, leadership, domain
    description TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_competences_tenant ON competences(tenant_id);

-- Employee Competences
CREATE TABLE IF NOT EXISTS employee_competences (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    employee_id UUID NOT NULL REFERENCES employees(id) ON DELETE CASCADE,
    competence_id UUID NOT NULL REFERENCES competences(id),
    level INTEGER CHECK (level BETWEEN 1 AND 5), -- 1=beginner, 2=intermediate, 3=advanced, 4=expert, 5=master
    acquired_date DATE,
    validated_by UUID REFERENCES employees(id),
    validation_date DATE,
    notes TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(employee_id, competence_id)
);

CREATE INDEX IF NOT EXISTS idx_emp_comp_employee ON employee_competences(employee_id);
CREATE INDEX IF NOT EXISTS idx_emp_comp_competence ON employee_competences(competence_id);

-- ==========================================
-- 3. DOCUMENT SYSTEM
-- ==========================================

-- Document Templates
CREATE TABLE IF NOT EXISTS document_templates (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES boc_tenants(id),
    name VARCHAR(255) NOT NULL,
    document_type VARCHAR(50) NOT NULL, -- contract, nda, policy, handbook, equipment_agreement
    description TEXT,
    content JSONB, -- strukturerat innehåll med variabler
    variables JSONB DEFAULT '[]', -- lista över variabler
    default_terms JSONB,
    language VARCHAR(5) DEFAULT 'sv',
    version INTEGER DEFAULT 1,
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_doc_templates_tenant ON document_templates(tenant_id);
CREATE INDEX IF NOT EXISTS idx_doc_templates_type ON document_templates(document_type);

-- Employee Documents
CREATE TABLE IF NOT EXISTS employee_documents (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    employee_id UUID NOT NULL REFERENCES employees(id) ON DELETE CASCADE,
    template_id UUID REFERENCES document_templates(id),
    document_type VARCHAR(50) NOT NULL,
    title VARCHAR(255) NOT NULL,
    
    -- Innehåll
    content JSONB,
    file_url VARCHAR(500),
    file_type VARCHAR(50),
    file_size INTEGER,
    
    -- Signering
    signature_status VARCHAR(20) DEFAULT 'draft', -- draft, sent, partially_signed, signed, expired
    signed_by_employee_at TIMESTAMP WITH TIME ZONE,
    signed_by_company_at TIMESTAMP WITH TIME ZONE,
    employee_signature_data JSONB,
    company_signature_data JSONB,
    signature_method VARCHAR(20), -- digital, manual, bankid
    
    -- Versionering
    version INTEGER DEFAULT 1,
    parent_id UUID REFERENCES employee_documents(id),
    
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    created_by UUID
);

CREATE INDEX IF NOT EXISTS idx_emp_docs_employee ON employee_documents(employee_id);
CREATE INDEX IF NOT EXISTS idx_emp_docs_type ON employee_documents(document_type);
CREATE INDEX IF NOT EXISTS idx_emp_docs_status ON employee_documents(signature_status);

-- ==========================================
-- 4. TRAINING SYSTEM
-- ==========================================

-- Trainings (Utbildningar)
CREATE TABLE IF NOT EXISTS trainings (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES boc_tenants(id),
    title VARCHAR(255) NOT NULL,
    description TEXT,
    category VARCHAR(50), -- onboarding, compliance, skill, safety, leadership
    format VARCHAR(20), -- video, text, quiz, workshop, mixed
    content JSONB, -- modulär struktur
    duration_minutes INTEGER,
    mandatory BOOLEAN DEFAULT false,
    valid_for_days INTEGER, -- hur länge certifiering gäller
    passing_score INTEGER DEFAULT 80, -- procent för godkänt
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_trainings_tenant ON trainings(tenant_id);
CREATE INDEX IF NOT EXISTS idx_trainings_category ON trainings(category);

-- Employee Trainings
CREATE TABLE IF NOT EXISTS employee_trainings (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    employee_id UUID NOT NULL REFERENCES employees(id) ON DELETE CASCADE,
    training_id UUID NOT NULL REFERENCES trainings(id),
    status VARCHAR(20) DEFAULT 'assigned', -- assigned, in_progress, completed, expired, failed
    progress_percent INTEGER DEFAULT 0,
    started_at TIMESTAMP WITH TIME ZONE,
    completed_at TIMESTAMP WITH TIME ZONE,
    expires_at TIMESTAMP WITH TIME ZONE,
    score INTEGER,
    certificate_url VARCHAR(500),
    certificate_number VARCHAR(100),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(employee_id, training_id)
);

CREATE INDEX IF NOT EXISTS idx_emp_trainings_employee ON employee_trainings(employee_id);
CREATE INDEX IF NOT EXISTS idx_emp_trainings_status ON employee_trainings(status);
CREATE INDEX IF NOT EXISTS idx_emp_trainings_expires ON employee_trainings(expires_at);

-- ==========================================
-- 5. TASK SYSTEM
-- ==========================================

-- Task Templates
CREATE TABLE IF NOT EXISTS task_templates (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES boc_tenants(id),
    title VARCHAR(255) NOT NULL,
    description TEXT,
    category VARCHAR(50), -- onboarding, role, compliance, project, recurring
    priority VARCHAR(20) DEFAULT 'medium', -- low, medium, high, critical
    estimated_duration_minutes INTEGER,
    checklist JSONB DEFAULT '[]',
    required_role_ids UUID[],
    required_competence_ids UUID[],
    instructions TEXT,
    resources JSONB DEFAULT '[]', -- länkar, dokument, etc.
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_task_templates_tenant ON task_templates(tenant_id);

-- Employee Tasks
CREATE TABLE IF NOT EXISTS employee_tasks (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    employee_id UUID NOT NULL REFERENCES employees(id) ON DELETE CASCADE,
    template_id UUID REFERENCES task_templates(id),
    title VARCHAR(255) NOT NULL,
    description TEXT,
    status VARCHAR(20) DEFAULT 'pending', -- pending, in_progress, completed, cancelled, overdue
    priority VARCHAR(20) DEFAULT 'medium',
    due_date DATE,
    completed_at TIMESTAMP WITH TIME ZONE,
    completed_by UUID REFERENCES employees(id),
    checklist_progress JSONB DEFAULT '[]',
    assigned_by UUID REFERENCES employees(id),
    assigned_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    source VARCHAR(50), -- onboarding, role, manual, automation, performance
    source_id UUID,
    notes TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_emp_tasks_employee ON employee_tasks(employee_id);
CREATE INDEX IF NOT EXISTS idx_emp_tasks_status ON employee_tasks(status);
CREATE INDEX IF NOT EXISTS idx_emp_tasks_due ON employee_tasks(due_date);

-- ==========================================
-- 6. PERFORMANCE SYSTEM
-- ==========================================

-- Performance Reviews
CREATE TABLE IF NOT EXISTS performance_reviews (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    employee_id UUID NOT NULL REFERENCES employees(id) ON DELETE CASCADE,
    reviewer_id UUID NOT NULL REFERENCES employees(id),
    review_period_start DATE NOT NULL,
    review_period_end DATE NOT NULL,
    review_type VARCHAR(20), -- annual, quarterly, probation, ad_hoc, 360
    
    -- Bedömningar
    overall_rating INTEGER CHECK (overall_rating BETWEEN 1 AND 5),
    ratings JSONB DEFAULT '{}', -- {competence_id: score, ...}
    goals JSONB DEFAULT '[]', -- [{goal, target, achievement, status}]
    strengths TEXT[],
    improvements TEXT[],
    
    -- Feedback
    employee_comments TEXT,
    reviewer_comments TEXT,
    development_plan TEXT,
    
    status VARCHAR(20) DEFAULT 'draft', -- draft, submitted, acknowledged, disputed
    acknowledged_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_perf_reviews_employee ON performance_reviews(employee_id);
CREATE INDEX IF NOT EXISTS idx_perf_reviews_status ON performance_reviews(status);

-- Performance KPIs
CREATE TABLE IF NOT EXISTS performance_kpis (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    employee_id UUID NOT NULL REFERENCES employees(id) ON DELETE CASCADE,
    kpi_name VARCHAR(100) NOT NULL,
    kpi_value DECIMAL(10,2),
    target_value DECIMAL(10,2),
    unit VARCHAR(20),
    period VARCHAR(20), -- weekly, monthly, quarterly, yearly
    period_start DATE,
    period_end DATE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_perf_kpis_employee ON performance_kpis(employee_id);
CREATE INDEX IF NOT EXISTS idx_perf_kpis_period ON performance_kpis(period_start);

-- ==========================================
-- 7. ONBOARDING SYSTEM
-- ==========================================

-- Onboardings
CREATE TABLE IF NOT EXISTS onboardings (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES boc_tenants(id),
    employee_id UUID NOT NULL REFERENCES employees(id),
    
    -- Status
    status VARCHAR(20) DEFAULT 'in_progress', -- in_progress, completed, cancelled
    progress_percent INTEGER DEFAULT 0,
    
    -- Steg
    steps JSONB DEFAULT '[]', -- [{step, status, completed_at, data}]
    
    -- Tidslinje
    started_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    completed_at TIMESTAMP WITH TIME ZONE,
    target_completion_date DATE,
    
    -- Ansvarig
    hr_manager_id UUID REFERENCES employees(id),
    buddy_id UUID REFERENCES employees(id), -- mentor/kompis
    
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_onboardings_tenant ON onboardings(tenant_id);
CREATE INDEX IF NOT EXISTS idx_onboardings_employee ON onboardings(employee_id);
CREATE INDEX IF NOT EXISTS idx_onboardings_status ON onboardings(status);

-- ==========================================
-- 8. AUDIT LOG
-- ==========================================

CREATE TABLE IF NOT EXISTS employee_audit_log (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    table_name VARCHAR(50) NOT NULL,
    record_id UUID NOT NULL,
    action VARCHAR(20) NOT NULL, -- create, update, delete
    old_values JSONB,
    new_values JSONB,
    changed_by UUID,
    changed_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    ip_address INET,
    user_agent TEXT
);

CREATE INDEX IF NOT EXISTS idx_audit_table ON employee_audit_log(table_name);
CREATE INDEX IF NOT EXISTS idx_audit_record ON employee_audit_log(record_id);
CREATE INDEX IF NOT EXISTS idx_audit_changed_at ON employee_audit_log(changed_at);

-- ==========================================
-- 9. TRIGGERS
-- ==========================================

-- Auto-update updated_at
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ language 'plpgsql';

-- Apply triggers
DROP TRIGGER IF EXISTS update_employees_updated_at ON employees;
CREATE TRIGGER update_employees_updated_at
    BEFORE UPDATE ON employees
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

DROP TRIGGER IF EXISTS update_employee_documents_updated_at ON employee_documents;
CREATE TRIGGER update_employee_documents_updated_at
    BEFORE UPDATE ON employee_documents
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

DROP TRIGGER IF EXISTS update_trainings_updated_at ON trainings;
CREATE TRIGGER update_trainings_updated_at
    BEFORE UPDATE ON trainings
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

DROP TRIGGER IF EXISTS update_employee_trainings_updated_at ON employee_trainings;
CREATE TRIGGER update_employee_trainings_updated_at
    BEFORE UPDATE ON employee_trainings
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

DROP TRIGGER IF EXISTS update_employee_tasks_updated_at ON employee_tasks;
CREATE TRIGGER update_employee_tasks_updated_at
    BEFORE UPDATE ON employee_tasks
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

DROP TRIGGER IF EXISTS update_performance_reviews_updated_at ON performance_reviews;
CREATE TRIGGER update_performance_reviews_updated_at
    BEFORE UPDATE ON performance_reviews
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

DROP TRIGGER IF EXISTS update_onboardings_updated_at ON onboardings;
CREATE TRIGGER update_onboardings_updated_at
    BEFORE UPDATE ON onboardings
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
