
-- Step 1: Merge duplicate accounts by account_number
DO $$
DECLARE
  rec RECORD;
  keep_id UUID;
  all_assoc_ids UUID[];
  existing_assoc_ids UUID[];
  merged UUID[];
BEGIN
  FOR rec IN
    SELECT account_number, array_agg(DISTINCT id) AS ids, array_agg(DISTINCT association_id) AS assoc_ids
    FROM chart_of_accounts
    GROUP BY account_number
    HAVING count(*) > 1
  LOOP
    keep_id := rec.ids[1];
    all_assoc_ids := rec.assoc_ids;

    SELECT COALESCE(association_ids, '{}') INTO existing_assoc_ids FROM chart_of_accounts WHERE id = keep_id;

    SELECT array_agg(DISTINCT val) INTO merged
    FROM (
      SELECT unnest(all_assoc_ids) AS val
      UNION
      SELECT unnest(existing_assoc_ids)
    ) sub;

    UPDATE chart_of_accounts SET association_ids = merged WHERE id = keep_id;

    -- Re-point FKs from duplicates to keeper
    UPDATE bills SET expense_account_id = keep_id WHERE expense_account_id = ANY(rec.ids) AND expense_account_id != keep_id;
    UPDATE vendors SET default_expense_account_id = keep_id WHERE default_expense_account_id = ANY(rec.ids) AND default_expense_account_id != keep_id;
    UPDATE journal_entries SET chart_of_account_id = keep_id WHERE chart_of_account_id = ANY(rec.ids) AND chart_of_account_id != keep_id;
    UPDATE zoho_account_mappings SET chart_of_account_id = keep_id WHERE chart_of_account_id = ANY(rec.ids) AND chart_of_account_id != keep_id;
    UPDATE chart_of_accounts SET parent_account_id = keep_id WHERE parent_account_id = ANY(rec.ids) AND parent_account_id != keep_id;

    DELETE FROM chart_of_accounts WHERE id = ANY(rec.ids) AND id != keep_id;
  END LOOP;
END $$;

-- Step 2: For remaining accounts, populate association_ids from association_id if empty
UPDATE chart_of_accounts
SET association_ids = ARRAY[association_id]
WHERE association_id IS NOT NULL AND (association_ids IS NULL OR array_length(association_ids, 1) IS NULL);

-- Step 3: Drop old unique constraint
ALTER TABLE chart_of_accounts DROP CONSTRAINT IF EXISTS chart_of_accounts_association_id_account_number_unique;

-- Step 4: Make association_id nullable
ALTER TABLE chart_of_accounts ALTER COLUMN association_id DROP NOT NULL;

-- Step 5: Add unique constraint on account_number alone
ALTER TABLE chart_of_accounts ADD CONSTRAINT chart_of_accounts_account_number_unique UNIQUE (account_number);
