# frozen_string_literal: true

module Pwb
  # PagePart consists of liquid template and block_contents which
  # can be parsed to generate html content.
  # Resulting html content is stored in page content model.
  #
  # Note: This model is NOT tenant-scoped. Use PwbTenant::PagePart for
  # tenant-scoped queries in web requests. This version is useful for
  # console work and cross-tenant operations.
# == Schema Information
#
# Table name: pwb_page_parts
#
#  id              :bigint           not null, primary key
#  block_contents  :json
#  editor_setup    :json
#  flags           :integer          default(0), not null
#  is_rails_part   :boolean          default(FALSE)
#  locale          :string
#  order_in_editor :integer
#  page_part_key   :string
#  page_slug       :string
#  show_in_editor  :boolean          default(TRUE)
#  template        :text
#  theme_name      :string
#  created_at      :datetime         not null
#  updated_at      :datetime         not null
#  website_id      :integer
#
# Indexes
#
#  index_page_parts_unique_per_website    (page_part_key,page_slug,website_id) UNIQUE
#  index_pwb_page_parts_on_page_part_key  (page_part_key)
#  index_pwb_page_parts_on_page_slug      (page_slug)
#  index_pwb_page_parts_on_website_id     (website_id)
#
  #
  class PagePart < ApplicationRecord
    self.table_name = 'pwb_page_parts'

    belongs_to :website, class_name: 'Pwb::Website', optional: true
    belongs_to :page, optional: true, class_name: 'Pwb::Page', foreign_key: 'page_slug', primary_key: 'slug'

    after_save :clear_template_cache
    after_destroy :clear_template_cache

    def as_json(options = nil)
      super({
        only: %w[is_rails_part page_part_key page_slug editor_setup block_contents show_in_editor id order_in_editor],
        methods: []
      }.merge(options || {}))
    end

    def self.create_from_seed_yml(yml_file_name)
      page_part_seed_file = Rails.root.join('db', 'yml_seeds', 'page_parts', yml_file_name)
      yml_file_contents = YAML.load_file(page_part_seed_file)
      unless where(page_part_key: yml_file_contents[0]['page_part_key'], page_slug: yml_file_contents[0]['page_slug']).count.positive?
        create!(yml_file_contents)
      end
    end

    # Get template content with fallback to file system
    # Priority: 1) Database, 2) Theme-specific file, 3) Default file
    def template_content
      cache_key = "page_part/#{id}/#{page_part_key}/#{website&.theme_name}/template"

      Rails.cache.fetch(cache_key, expires_in: cache_duration) do
        load_template_content
      end
    end

    private

    def cache_duration
      Rails.env.development? ? 5.seconds : 1.hour
    end

    def load_template_content
      # 1. Database Override (highest priority)
      return self[:template] if self[:template].present?

      theme_name = website&.theme_name || 'default'

      # 2. Theme-Specific File
      theme_path = Rails.root.join("app/themes/#{theme_name}/page_parts/#{page_part_key}.liquid")
      return File.read(theme_path) if File.exist?(theme_path)

      # 3. Default File
      default_path = Rails.root.join("app/views/pwb/page_parts/#{page_part_key}.liquid")
      return File.read(default_path) if File.exist?(default_path)

      # 4. Fallback to empty string if nothing found
      ''
    end

    def clear_template_cache
      cache_key = "page_part/#{id}/#{page_part_key}/#{website&.theme_name}/template"
      Rails.cache.delete(cache_key)
    end
  end
end
