/*
 * -------------------------------------------------------
 * Shared Templates Across Hierarchy
 *
 * 1. Add shared_with_hierarchy flag to newsletter_templates
 * 2. Create document_templates table with hierarchy sharing
 * 3. Template cloning function for child orgs
 * 4. Hierarchy-aware RLS for template reads
 * -------------------------------------------------------
 */

-- =====================================================
-- 1. Newsletter Templates: add sharing flag
-- =====================================================

ALTER TABLE public.newsletter_templates
  ADD COLUMN IF NOT EXISTS shared_with_hierarchy boolean NOT NULL DEFAULT false;

-- Allow child orgs to read parent's shared templates
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_policies
    WHERE schemaname = 'public' AND tablename = 'newsletter_templates'
      AND policyname = 'newsletter_templates_hierarchy_read'
  ) THEN
    EXECUTE 'CREATE POLICY newsletter_templates_hierarchy_read
      ON public.newsletter_templates
      FOR SELECT TO authenticated
      USING (
        shared_with_hierarchy = true
        AND public.has_role_on_account_or_ancestor(account_id)
      )';
  END IF;
END $$;

-- =====================================================
-- 2. Document Templates table
-- =====================================================

CREATE TABLE IF NOT EXISTS public.document_templates (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  account_id uuid NOT NULL REFERENCES public.accounts(id) ON DELETE CASCADE,
  name text NOT NULL,
  description text,
  template_type text NOT NULL DEFAULT 'generic'
    CHECK (template_type IN (
      'generic', 'member_card', 'invoice', 'receipt',
      'certificate', 'letter', 'label', 'report'
    )),
  -- Template content: HTML with variable placeholders like {{member.first_name}}
  body_html text NOT NULL DEFAULT '',
  -- Available variables for this template
  variables jsonb NOT NULL DEFAULT '[]'::jsonb,
  -- Page settings
  page_format text NOT NULL DEFAULT 'A4'
    CHECK (page_format IN ('A4', 'A5', 'A6', 'letter', 'label')),
  orientation text NOT NULL DEFAULT 'portrait'
    CHECK (orientation IN ('portrait', 'landscape')),
  -- Hierarchy sharing
  shared_with_hierarchy boolean NOT NULL DEFAULT false,
  -- Meta
  is_default boolean NOT NULL DEFAULT false,
  sort_order integer NOT NULL DEFAULT 0,
  created_by uuid REFERENCES auth.users(id) ON DELETE SET NULL,
  created_at timestamptz NOT NULL DEFAULT now(),
  updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX IF NOT EXISTS ix_document_templates_account
  ON public.document_templates(account_id);

CREATE INDEX IF NOT EXISTS ix_document_templates_type
  ON public.document_templates(account_id, template_type);

ALTER TABLE public.document_templates ENABLE ROW LEVEL SECURITY;

REVOKE ALL ON public.document_templates FROM authenticated, service_role;
GRANT SELECT, INSERT, UPDATE, DELETE ON public.document_templates TO authenticated;
GRANT ALL ON public.document_templates TO service_role;

-- Own account read/write
CREATE POLICY document_templates_select ON public.document_templates
  FOR SELECT TO authenticated
  USING (public.has_role_on_account(account_id));

CREATE POLICY document_templates_mutate ON public.document_templates
  FOR ALL TO authenticated
  USING (public.has_permission(auth.uid(), account_id, 'documents.generate'::public.app_permissions));

-- Hierarchy: child orgs can read parent's shared templates
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_policies
    WHERE schemaname = 'public' AND tablename = 'document_templates'
      AND policyname = 'document_templates_hierarchy_read'
  ) THEN
    EXECUTE 'CREATE POLICY document_templates_hierarchy_read
      ON public.document_templates
      FOR SELECT TO authenticated
      USING (
        shared_with_hierarchy = true
        AND public.has_role_on_account_or_ancestor(account_id)
      )';
  END IF;
END $$;

CREATE TRIGGER trg_document_templates_updated_at
  BEFORE UPDATE ON public.document_templates
  FOR EACH ROW EXECUTE FUNCTION public.update_account_settings_timestamp();

-- =====================================================
-- 3. Template cloning function
-- =====================================================

-- Clone a shared template into a child org's own templates
CREATE OR REPLACE FUNCTION public.clone_template(
  p_template_type text, -- 'newsletter' or 'document'
  p_template_id uuid,
  p_target_account_id uuid,
  p_new_name text DEFAULT NULL
)
RETURNS uuid
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = ''
AS $$
DECLARE
  v_new_id uuid;
  v_caller_id uuid;
  v_source_account_id uuid;
BEGIN
  v_caller_id := (SELECT auth.uid());

  -- Verify caller has a role on the target account
  IF NOT public.has_role_on_account(p_target_account_id) THEN
    RAISE EXCEPTION 'Keine Berechtigung für die Zielorganisation';
  END IF;

  IF p_template_type = 'newsletter' THEN
    -- Get source account for verification
    SELECT account_id INTO v_source_account_id
    FROM public.newsletter_templates WHERE id = p_template_id;

    IF v_source_account_id IS NULL THEN
      RAISE EXCEPTION 'Vorlage nicht gefunden';
    END IF;

    -- Must be shared or from own account
    IF v_source_account_id != p_target_account_id THEN
      IF NOT EXISTS (
        SELECT 1 FROM public.newsletter_templates
        WHERE id = p_template_id AND shared_with_hierarchy = true
      ) THEN
        RAISE EXCEPTION 'Vorlage ist nicht für die Hierarchie freigegeben';
      END IF;
    END IF;

    INSERT INTO public.newsletter_templates (
      account_id, name, subject, body_html, body_text, variables
    )
    SELECT
      p_target_account_id,
      COALESCE(p_new_name, name || ' (Kopie)'),
      subject, body_html, body_text, variables
    FROM public.newsletter_templates
    WHERE id = p_template_id
    RETURNING id INTO v_new_id;

  ELSIF p_template_type = 'document' THEN
    SELECT account_id INTO v_source_account_id
    FROM public.document_templates WHERE id = p_template_id;

    IF v_source_account_id IS NULL THEN
      RAISE EXCEPTION 'Vorlage nicht gefunden';
    END IF;

    IF v_source_account_id != p_target_account_id THEN
      IF NOT EXISTS (
        SELECT 1 FROM public.document_templates
        WHERE id = p_template_id AND shared_with_hierarchy = true
      ) THEN
        RAISE EXCEPTION 'Vorlage ist nicht für die Hierarchie freigegeben';
      END IF;
    END IF;

    INSERT INTO public.document_templates (
      account_id, name, description, template_type,
      body_html, variables, page_format, orientation, created_by
    )
    SELECT
      p_target_account_id,
      COALESCE(p_new_name, name || ' (Kopie)'),
      description, template_type,
      body_html, variables, page_format, orientation, v_caller_id
    FROM public.document_templates
    WHERE id = p_template_id
    RETURNING id INTO v_new_id;

  ELSE
    RAISE EXCEPTION 'Ungültiger Vorlagentyp: %', p_template_type;
  END IF;

  RETURN v_new_id;
END;
$$;

GRANT EXECUTE ON FUNCTION public.clone_template(text, uuid, uuid, text)
  TO authenticated, service_role;

-- =====================================================
-- 4. List shared templates across hierarchy
-- =====================================================

CREATE OR REPLACE FUNCTION public.list_hierarchy_shared_templates(
  root_account_id uuid,
  p_template_type text DEFAULT NULL -- 'newsletter', 'document', or NULL for both
)
RETURNS TABLE (
  id uuid,
  account_id uuid,
  account_name varchar,
  template_source text, -- 'newsletter' or 'document'
  name text,
  description text,
  template_type text,
  shared_with_hierarchy boolean,
  created_at timestamptz
)
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = ''
AS $$
BEGIN
  IF NOT public.has_role_on_account(root_account_id) THEN
    RETURN;
  END IF;

  RETURN QUERY
  -- Newsletter templates
  SELECT
    nt.id,
    nt.account_id,
    a.name AS account_name,
    'newsletter'::text AS template_source,
    nt.name,
    NULL::text AS description,
    'newsletter'::text AS template_type,
    nt.shared_with_hierarchy,
    nt.created_at
  FROM public.newsletter_templates nt
  JOIN public.accounts a ON a.id = nt.account_id
  WHERE nt.account_id IN (SELECT d FROM public.get_account_descendants(root_account_id) d)
    AND nt.shared_with_hierarchy = true
    AND (p_template_type IS NULL OR p_template_type = 'newsletter')

  UNION ALL

  -- Document templates
  SELECT
    dt.id,
    dt.account_id,
    a.name AS account_name,
    'document'::text AS template_source,
    dt.name,
    dt.description,
    dt.template_type,
    dt.shared_with_hierarchy,
    dt.created_at
  FROM public.document_templates dt
  JOIN public.accounts a ON a.id = dt.account_id
  WHERE dt.account_id IN (SELECT d FROM public.get_account_descendants(root_account_id) d)
    AND dt.shared_with_hierarchy = true
    AND (p_template_type IS NULL OR p_template_type = 'document')

  ORDER BY created_at DESC;
END;
$$;

GRANT EXECUTE ON FUNCTION public.list_hierarchy_shared_templates(uuid, text)
  TO authenticated, service_role;
